How to Use the xargs Command on Linux

A Linux terminal prompt on a laptopFatmawati Achmad Zaenuri / Shutterstock

You need to chain Linux commands together, but one of them does not accept pipeline entries? xargs can take the result of one command and send it to another command as parameters.

All standard Linux utilities have three data streams associated with them. They are the standard input stream (stdin), the standard output stream (stdout) and the standard error stream (stderr).

These streams work with text. We send an entry (stdin) to a command using text and the response (stdout) is written in the terminal window as text. Error messages are also written to the terminal window as text (stderr).

One of the great features of Linux and Unix-like operating systems is the ability to direct the output stdout of a command to the input stdin of a second command. The first command does not worry that its output is not going into a terminal window, and the second command does not worry that its input does not come from a keyboard.

Although all Linux commands have the three standard streams, they do not all accept the standard output of another command as input to their stdin. This means that you can not direct the entrance to them.

xargs is a command to create runtime pipelines using standard data feeds. By using xargs, we can make commands such as echo, rm, and mkdir accept standard input as arguments.

The xargs command

xargs will accept the entry piped. It can also accept entries from a file. xargs uses this input as a parameter for the commands with which we told it to work. If we do not tell xargs to work with a specific command, it will default to echo.

We can use this to show how xargs will always generate a single output line, even from a multiline entry.

If we use the -1 option (list one file per line) with ls, we get a single column of file names.

ls -1 ./*.sh

v in a terminal window

This lists the shell script files in the current directory.

exit from ls in a terminal window

We get a single column as expected. If we pass it through xargs, what do we get?

ls -1 ./*.sh | xargs

ls -1 ./*.sh | xargs in a terminal window

The output is written to the terminal window as a long text stream.

ls goes through xargs in a terminal window

It is this ability that allows xargs to feed parameters into other commands.

Use xargs with wc

We can use xargs so that we can easily count the words, characters and lines in several files.

ls * .page | xargs wc

ls * .page | wc xargs in a terminal window

This is what happens:

ls lists the * .page files and passes the list to xargs.
xargs passes the filenames to wc.
wc treats filenames as if it had received them as command line parameters.

exit wc in a terminal window

The statistics for each file are displayed with a grand total.

Using xargs with confirmation

We can use the -p (interactive) option for xargs to ask us to confirm that we are satisfied with its execution.

If we pass a string of filenames to touch, via xargs, touch will create files for us.

echo one two three & # 39; | xargs -p touch

echo one two three & # 39; | xargs -p touch in a terminal window

The command that will be executed is displayed and xargs waits for us to answer by typing "y" or "Y", or "n" or "N", then pressing Enter.

If you simply press Enter, it is treated as "n". The command is executed only if you type "y" or "Y".

xargs requesting confirmation in a terminal window

We pressed "y" and pressed Enter. We can use ls to verify that the files have been created.

ls one two three

exit from ls in a terminal window

Use xargs with multiple commands

We can use multiple commands with xargs using the -I option (initial arguments).

This option defines a "replacement string". Whenever the token of the replacement string appears on the command line, the values ​​supplied to xargs are inserted.

Use the tree command to examine the subdirectories of the current directory. The -d (directory) option allows the tree to skip files and report only to directories.

tree -d

tree -d in a terminal window

There is only one subdirectory called "images".

In a file called "Directories.txt" we have the names of some directories we want to create. We can watch its content using chat.

cat.txt directories

cat directory.txt in a terminal window

We will use this as input for xargs. The order we are going to make is:

cat directories.txt | xargs -I% sh -c & echo%; mkdir% & # 39;

It breaks down like this:

cat Directories.txt |: This pushes the contents of the file directrories.txt (all new directory names) into xargs.
xargs -I%: This defines a "replacement string" with the token "%".
sh -c: This starts a new subshell. The -c command tells the shell to read commands from the command line.
& Echo% mkdir% ': each of the "%" tokens will be replaced by the directory names passed by xargs. The echo command will display the directory name. the mkdir command will create the directory.

cat directories.txt | xargs -I% sh -c & echo%; mkdir% & # 39; in a terminal window

The directories are listed one by one.

output of xargs in a terminal window

We can use the tree one more time to verify that the directories have been created.

tree -d

output of the tree in a terminal window

Copy files to multiple locations

We can use xargs to allow us to copy files to multiple locations with a single command.

We are going to channel the names of two directories into xargs as input parameters. We will tell xargs to pass only one of these parameters at a time to the command with which it works.

In this case, the command is cp. The effect is therefore to call cp twice, each time with one of the two directories as the command line parameter. The xargs parameter that allows this is the -n (maximum number) option. We will define this to be one.

We also use the -v (verbose) option with cp to report what is happening.

echo ~ / Backups / ~ / Documents / files-pages / | xargs -n 1 cp -v ./*.page

echo ~ / Backups / ~ / Documents / files-pages / | xargs -n 1 cp -v ./*.page in a terminal window

The files are copied to both directories, one directory at a time. cp reports each file copy action so that we can see it unfold.

output of xargs and cp in a terminal window

Deleting files in nested directories

If file names have strange spaces and characters, such as newline characters, xargs will not be able to interpret them correctly. We can solve this problem by using the -0 option (null terminator). This tells xargs to use the null character as the final delimiter for file names.

We will use find in this example. find at his own option for deal with spaces and strange characters in file names. This is the -print0 option (full name, null character).

find . -name "* .png" -type f -print0 | xargs -0 rm -v -rf "{}"

It breaks down like this:

find . -name "* .png": find will find in the current directory "." the objects whose name corresponds to "* .png" and which are files (type -f).
-print0: names will be terminated with a null character, and spaces and strange characters will be taken into account.
xargs -0: xargs will also consider file names to be terminated with a null character, and strange spaces and characters will not be a problem.
rm -v -rf "{}": rm will be commented and report what happens (-v). It will be recursive (-r) and browse nested subdirectories, and delete files without prompt (-f). The "{}" is replaced by each file name.

find . -name "* .png" -type f -print0 | xargs -0 rm -v -rf "{}" in a terminal window

All subdirectories are searched and the files corresponding to the search template are deleted.

Rm output in a terminal window

Delete nested directories

Let's say we want to delete a set of nested subdirectories. the tree will let us see them.

tree -d

tree -d in a terminal window

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"

This command will use find to perform a recursive search in the current directory. The target of the search is a directory called "level_one". Directory names are passed via xargs to rm.

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}" in a terminal window

The only significant changes between this command and the previous command are as follows: the search term is the name of the highest directory and -d type tells find to search for directories and not files.

find output and xargs and rm in a terminal window

The name of each directory is printed as it is deleted. We can check with the tree:

tree -d

tree -d in a terminal window

All nested subdirectories are deleted.

Deleting all files except for a file type

We can use find, xargs and rm to delete all files, except the type we want to keep. It's a bit counterintuitive, but we provide the name of the type of file we want to keep, not the names of those we want to delete.

The -not option tells find to return the names of files that do not match the search pattern. We still use the -I option (initial arguments) with xargs. This time, the chain replacement token we define is "{}". This will behave exactly the same way as the chain replacement token we generated earlier, which was a "%".

find . -type f -not -name "* .sh" -print0 | xargs -0 -I {} rm -v {}

find . -type f -not -name "* .sh" -print0 | xargs -0 -I {} rm -v {} in a terminal window

We can check with ls. The only remaining files in the directory are those that match the search pattern "* .sh".

ls -l

exit from ls in a terminal window

Create an archive file with Xargs

We can use find to find files and send them via xargs to tar to create an archive file.

We will search in the current directory. The search pattern is "* .page", so we will look for ".page" files.

find ./ – name "* .page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz

find ./ - name "* .page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz in a terminal window

The files are listed as expected when the archive file is created.

tar output in a terminal window

The data mediator

Sometimes you need a small scaffold when stacking things. xargs bridges the gap between commands that retrieve information and commands that are not designed to integrate them.

Xargs and find have a very large number of options. We encourage you to check out their manual pages for more information.

Advertisements

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.