eXtended ARGumentS
Previously on Dec 12 I showed how you can execute a command on files
matching a pattern with find -exec.
However, it has some limitations.
First it obviously only works for find.
Second the exec doesn’t have a shell, meaning you can’t use it with many of
the cool shell tricks you are learning about in this series of post.
The xarg command (short for “extended arguments”) doesn’t have these
limitations.
It works for any other command.
The basic idea is that it reads from stdin and executes another command for
each item in the input.
Here is a simple example:
ls | xargs echo
It uses ls to list files in current working directory then pipe the output to
xargs which will run echo for each filename.
Just using xargs with echo command isn’t very interesting.
So let’s look at a more useful example.
Say I want to add all images from my phone to a compressed archive file for easy backup.
find ~/Pictures -name "P_*.jpg" -type f -print0 | xargs -0 tar -cvzf images.tar.gz
I got all my images in ~/Pictures.
Images taking with my phone has a filename that starts with “P_” and ends with
“.jpg”.
tar -cvzf add files to a compressed archive.
By default, xargs will use whitespace characters as separator between items.
That would create problems if we have files with a space in the name.
So the -print0 flag is used output filenames separated null character, and
-0 tells xargs to separate based on null character.
Instead of archiving, we could just copy the files directly to a backup location.
find ~/Pictures -name "P_*.jpg" -type f -print0 | xargs -0 -I {} cp {} /mnt/backup/images
Where {} is used as placeholder for the filename.
There are many other ways that xargs can be used.
Say we have a file “filenames.txt” with a folder structure.
Could look like:
apps/frontend/
apps/backend/
libs/
scripts/
Then we can create folders matching the structure with:
cat filenames.txt | xargs mkdir -p
The xargs command is super powerful and can be used with other commands in
countless ways.
It allows for neat one-lines, with explicit loops.