'find also allows you to pass multiple filenames as args to you script. On the bash side, you really only need to realize that you must make you strings into bash words typically by using "double quotes", or some other mechanism like using IFS, or find's \+ |sed 's/home//' I disagree with the bash bashers, because bash, along with the *nix tool set, is quite adept at handling files (including ones whose names have embedded whitespace).Īctually, find gives you fine grain control over choosing which files to process. Which would be especially troublesome with the following common solution: chmod +x. iname '*space*' -print0 | xargs -0 -n 1. Note that it handles spaces and newlines perfectly well, $ touch 'A space-age We can clearly see the effect xargs has on its input - and the effect of -n in particular - by using a script which echoes its arguments in a more precise manner than echo. (You can echo short input | xargs -show-limits to see how many bytes are allowed in a command line.) What does xargs do, exactly? Had we omitted that option, xargs would have passed as many as possible to echo. Because we specified the -n 1 option, xargs will only pass one argument at a time to echo. ) and any sub-directory, and pass each of them as an argument to the echo command. This will find every PDF (via -iname '*.pdf') in the current directory (. iname '*.pdf' -print0 | xargs -0 -n 1 echo For example, say you wanted a listing of every PDF file within the current directory. Using find -print0 combined with xargs -0 is completely robust against legal file names, and is one of the most extensible methods available. The for loop version avoids that but at the price that, even if you apply the $IFS solution to avoid issues with spaces, you will then get in trouble if the find returns too many files.Īt some point the correct fix for all of this becomes doing it in a language such as Perl or Python instead of shell. This does have one other caveat attached: what happens inside the while loop may take place in a subshell, depending on the exact shell you're using, so variable settings may not persist. Also remember to set $IFS back after using it, because not doing so will cause bewildering errors later. If the path name is a directory, du reports the total amount of file space that is used by all files in that directory and in each subdirectory in its hierarchy. Remember to also quote $i when using it, to avoid other things interpreting the spaces later. In the -print0 case, find prints its output with a null separator, and then xargs splits on this. In the first case find takes care of the file name escaping. That said, there is a way to almost do what you want: oIFS=$IFSįind. Another method, depending on what you want to do with the output from find, is to either directly use -exec with the find command, or use -print0 and pipe it into xargs -0. This is even listed as the first entry in the BashPitfalls page. Ideally you don't do it that way at all, because parsing filenames properly in a shell script is always difficult (fix it for spaces, you'll still have problems with other embedded characters, in particular newline).
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |