How to use the xargs command on Linux

Hello everyone, this is Liang Xu.

When using Linux, have you ever encountered a situation where you need to string some commands together, but one of the commands does not accept pipe input? In this case, we can use the xargscommand. xargsYou can send the output of one command as a parameter to another command.

In Linux, all standard applications have three data streams associated with them. They are the standard input stream (stdin), standard output stream (stdout) and standard error stream (stderr). These streams are run through text. We use text to send the input (stdin) to the command, and the response (stdout) will be displayed in the terminal window as text. Error messages are also displayed in the terminal window (stderr) in text form.

A major feature of Linux and Unix-like operating systems is the ability to pass the standard output stream of one command to the standard input stream of another command. The first command does not care whether its output is written to the terminal window, and the second command does not care whether its input comes from the keyboard.

Although all Linux commands have three standard streams, not all commands accept the standard output of another command as input to its standard input stream. Therefore, we cannot pass input to these commands through pipes.

xargsIt is a command that uses standard data flow to build an execution pipeline. By using the xargscommand we can make echo, rmand mkdirso on command accepts standard input as their parameters.

xargs command

xargsAccept pipeline input, you can also accept input from a file. xargsUse this input as a parameter of the command we specified. If we do not xargsspecify a specific command, it will be used by default echo. xargsAlways generate a single line of output, even if the input data is multiple lines.

If we use lsthe -1(each line lists a file) option, you'll get a file name:

$ ls -1 ./*.sh

This command lists the shell script files in the current directory.

xargsWhat kind of effect will we get if we pass the output result through the pipeline ?

$ ls -1 ./*.sh | xargs

As you can see, the output is written to the terminal as a long string of text. This shows that xargsyou can pass the output as a parameter to other commands.

Use xargs with wc command

We can use the xargscommand make it easy for wca command to calculate the number of words in multiple files, the number of characters and lines

$ ls *.c | xargs wc

The execution results are as follows:

The command execution result shows the statistical information and total number of each file.

This command performed the following actions:

  • lsAll the .page files are listed, and the list is passed to xargs.
  • xargsPass all file names to wc.
  • wc Treat these file names as command line parameters.

Use xargs with confirmation message

We can use -p(interactive) option to make xargsprompt Are we going to the next step.

If we pass xargspassed to the string string filename touchcommand touchwill create these files.

$ echo 'one two three' | xargs -p touch

Displays the command to be executed on the terminal, xargswaiting for us to enter y, or Y, nor Npress Enter to respond. If it is only pressed Enter, it is considered n. Only when we when the input yor Ywhen the command is executed.

We press yand Enter, and then use lsto check whether the file has been created.

$ ls one two three

Use xargs with multiple commands

We can use -Ithe (initial parameters) option to xargsbe used with multiple commands. This option is defined 替换字符串. Anywhere on the command line appears the replacement string, we will provide to insert xargsvalues.

It's a bit abstract, let's explain it with an example.

We first use treeto view the current directory in a subdirectory of command. The -d(directory) option allows the treecommand to ignore the file, only the output directory.

$ tree -d

There is only one subdirectory images now.

In the directories.txt file, we have the names of some directories we want to create. We first use catto view its contents.

$ cat directories.txt

We pass these contents as input data xargsand execute the following commands:

$ cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'

This command performed the following actions:

  • cat directories.txt : Pass the contents of the directories.txt file (names of all directories to be created) to xargs.
  • xargs -I % : The replacement string is defined %.
  • sh -c : Start a new subshell. -c(Commond) Let the shell read commands.
  • 'echo%; mkdir%' : each will be replaced xargspass over the directory name. echoCommand to print the directory name, mkdircommand to create a directory.

Command execution result:

We can treeverify whether you have created a directory has been created.

$ tree -d

Copy files to multiple locations

We can use the xargscommand to use a command to copy the files to multiple locations.

First, pass the names of the two directories through a pipe xargs. And let xargstime only one of the parameters passed to the command being used.

Want to call cptwice each using one of the two directories as command line arguments, we can be xargsof -n1 to implement (max number) option is set.

There is also used -v(verbose details) option, so that cpoperation of the feedback being performed.

$ echo ~/dir1/ ~/dir2/ | xargs -n 1 cp -v ./*.c

We copied the files to two directories, one directory at a time. cpThe detailed information was fed back, allowing us to see what actions were taken.

Delete files in nested directories

If the file name contains spaces or other special characters (such as line breaks), xargsthese file names will not be interpreted correctly. We can use the -0(null terminator) option to solve this problem. In this case, xargsthe use nullof characters as the file name of the final delimiter.

Here we findcommand as an example. findThere are its own options to deal with spaces and special characters in file names, that is, the -print0(full name, empty character) option.

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

This command performs the following actions:

  • find. -name “*.png” : findSearch for objects whose name matches *.png from the current directory, and type -fspecify to search only for files.
  • -print0 : The name will end with a null character, and spaces and special characters are reserved.
  • xargs -0 : xargsIt will also be considered that the file name ends with a null value, and spaces and special characters will not cause problems.
  • rm -v -rf "{}" : rmfeedback the ongoing operation ( -v), perform the operation recursively (-r), and delete the file directly without sending an error message ( -f). Replace "{}" with each file name.

After the command is executed, all subdirectories will be searched and the matching files will be deleted.

Delete nested directories

Suppose we want to delete a set of nested subdirectories, first use it treeto view.

$ tree -d

$ find . -name "level_one" -type d -print0 | xargs -0 rm -v -rf "{}"

This command uses find to search recursively in the current directory. The search target is a directory named level_one, and then the directory name is xargspassed to rm.

The difference between this command and the previous command is that the searched item is the name of the topmost directory, and it -type dspecifies the directory to find, not the file.

The name of each directory is printed out when deleted. We can treecheck the effect again:

$ tree -d

All nested subdirectories have been deleted.

Delete all files except one file type

We can use find, xargsand rmdelete all types of files and keep only one type of file we want to keep. This needs to provide the type of file you want to keep.

-notOptions allow findthe return of all the search pattern does not match the file name. At this point we again use xargsthe -I(initial parameters) option. The replacement string defined this time is {}. This is the replacement string we used before the %effect is the same.

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

After the command is executed, we then pass lsto confirm the results. We can see, the directory and only the *.shfiles that match.

$ ls -l

Use Xargs to create compressed files

We can use the findcommand to search for files by xargsfile name passed to the tarcommand to create a compressed file.

We will search in the current directory * .shfiles.

$ find ./ -name "*.sh" -type f -print0 | xargs -0 tar -cvzf script_files.tar.gz

The command execution result will list all .sh files and create a compressed file.

Finally, recently many friends asked me for the Linux learning roadmap , so based on my experience, I spent a month staying up late in my spare time and compiled an e-book. Whether you are in an interview or self-improvement, I believe it will help you! The directory is as follows:

Give it to everyone for free, just ask you to give me a thumbs up!

Ebook | Linux development learning roadmap

I also hope that some friends can join me to make this e-book more perfect!

Gain? I hope the old irons will have a three-strike combo so that more people can read this article

Recommended reading:

Guess you like

Origin blog.csdn.net/yychuyu/article/details/108209770