xargs is particularly useful when you have a list of filepaths on stdin and want to do something with them. For example:
$ git ls-files "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
Let's examine this step by step:
$ git ls-files "*.tex"
In other words, our input is a list of paths that we want to do something to.
To find out what xargs does with these paths, a nice trick is to add
echo before your command, like so:
$ git ls-files "*.tex" | xargs -n 1 echo sed -i "s/color/colour/g"
sed -i "s/color/colour/g" tex/ch1/intro.tex
sed -i "s/color/colour/g" tex/ch1/motivation.tex
-n 1 argument will make xargs turn each line into a command of its own. The
sed -i "s/color/colour/g" command will replace all occurrences of
colour for the specified file.
Note that this only works if you don't have any spaces in your paths. If you do, you should use null terminated paths as input to xargs by passing the
-0 flag. An example usage would be:
$ git ls-files -z "*.tex" | xargs -0 -n 1 sed -i "s/color/colour/g"
Which does the same as what we described above, but also works if one of the paths has a space in it.
This works with any command that produces filenames as output such as
locate. If you do happen to use it in a git repository with a lot of files though, it might be more efficient to use it with
git grep -l instead of
git ls-files, like so:
$ git grep -l "color" "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
git grep -l "color" "*.tex" command will give a list of "*.tex" files containing the phrase "color".