------------------------------------------------------------------------ xargs: feeding argumets to a utility ------------------------------------------------------------------------ "The xargs utility reads space, tab, newline and end-of-file delimited strings from the standard input and executes utility with the strings as arguments." The primary value of xargs is to take an input stream (organized filen names, one per line) and feed them to a utility with appropriate reformulation (either all file names on one line or a certain number of files per line etc). The default utility is /bin/echo -------------------------------------------------------------------------------- I. xargs as a matrix generator -------------------------------------------------------------------------------- $ seq 4 1 2 3 4 $ seq 4 | xargs 1 2 3 4 $ seq 4 | xargs -n 2 1 2 3 4 Note that xargs takes inputs which are separated by a tab, space, new line etc and convert to a row $ touch {A..Z}.rat $ ls *.rat A.rat D.rat G.rat J.rat M.rat P.rat S.rat V.rat Y.rat B.rat E.rat H.rat K.rat N.rat Q.rat T.rat W.rat Z.rat C.rat F.rat I.rat L.rat O.rat R.rat U.rat X.rat $ ls *.rat | xargs A.rat B.rat C.rat .... X.rat Y.rat Z.rat -------------------------------------------------------------------------------- II. xargs diagnostics -------------------------------------------------------------------------------- $ seq 4 | xargs -t # the switch "-t" displays the excecution of commands /bin/echo 1 2 3 4 1 2 3 4 -------------------------------------------------------------------------------- III. xargs and find is a great combination -------------------------------------------------------------------------------- find, though arcane, is a powerful way to find files. Once you have the files you may wish to process them in some fashion. This is where xargs is useful The general format is "find ... | xargs action" where ... encompasses find instructions and "action" is a utility. $ find ... | xargs rm #delete all files found by find $ find ... | xargs grep 'pattern' #find files, grep them for 'pattern' Say the find ends up finding a.txt, b.txt and c.txt. By preceding the action ("rm") with echo you can see the command formulated by xargs. This is a very useful diagnostic. $ find ... | xargs echo rm rm a.txt b.txt c.txt -------------------------------------------------------------------------------- IV. Sometimes you may need rows of instructions -------------------------------------------------------------------------------- Say you have a series of files (found by find). Let us call them as a.txt b.txt and c.txt. You wish to copy them over by a master file. Ideall you want commands like cp MasterFile.txt a.txt cp MasterFile.txt b.txt cp MasterFile.txt c.txt $ find ... | xargs -echo cp MasterFile.xt cp a.txt b.txt c.txt MasterFile.txt #not what you want $ find ... | xarss -n 1 -echo cp MasterFilex.txt cp MasterFile.txt a.txt cp MasterFile.txt b.txt cp MasterFile.txt c.txt #exactly what you want -------------------------------------------------------------------------------- V. Operate on each input separately -------------------------------------------------------------------------------- Some utilities do not take multiple inputs. Examples "mv". In this case you want the tool to be supplied by each input on a separate line. The option "I {}" will replace each input one by one and then send it to the shell The "p" option "pauses" and asks you to confirm action for each file $ ls *.txt | xargs -t -n 1 -I {} mv {} {}.old #rename files to files.old $ ls *.txt | xargs -t -n1 -p -I{} mv {} {}.old #rename files to files.old If there are weird file names then use '{}' instead of {} #e.g. To convert all files in a dir from png to jpg. # $ find . -name "*png" | xargs -l -i basename "{}" ".png" | xargs -l -i convert -quality 85% "{}.png" "{}.jpg" The "-l" makes it process one line at time. The "-i" makes the "{}" to stand for filename The "basename" strips the suffix. --------------------------------------------------------------------------------