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 xargs
command. xargs
You 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.
xargs
It is a command that uses standard data flow to build an execution pipeline. By using the xargs
command we can make echo
, rm
and mkdir
so on command accepts standard input as their parameters.
xargs command
xargs
Accept pipeline input, you can also accept input from a file. xargs
Use this input as a parameter of the command we specified. If we do not xargs
specify a specific command, it will be used by default echo
. xargs
Always generate a single line of output, even if the input data is multiple lines.
If we use ls
the -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.
xargs
What 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 xargs
you can pass the output as a parameter to other commands.
Use xargs with wc command
We can use the xargs
command make it easy for wc
a 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:
ls
All the .page files are listed, and the list is passed toxargs
.xargs
Pass all file names towc
.wc
Treat these file names as command line parameters.
Use xargs with confirmation message
We can use -p
(interactive) option to make xargs
prompt Are we going to the next step.
If we pass xargs
passed to the string string filename touch
command touch
will create these files.
$ echo 'one two three' | xargs -p touch
Displays the command to be executed on the terminal, xargs
waiting for us to enter y
, or Y
, n
or N
press Enter to respond. If it is only pressed Enter
, it is considered n
. Only when we when the input y
or Y
when the command is executed.
We press y
and Enter, and then use ls
to check whether the file has been created.
$ ls one two three
Use xargs with multiple commands
We can use -I
the (initial parameters) option to xargs
be used with multiple commands. This option is defined 替换字符串
. Anywhere on the command line appears the replacement string, we will provide to insert xargs
values.
It's a bit abstract, let's explain it with an example.
We first use tree
to view the current directory in a subdirectory of command. The -d
(directory) option allows the tree
command 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 cat
to view its contents.
$ cat directories.txt
We pass these contents as input data xargs
and 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 replacedxargs
pass over the directory name.echo
Command to print the directory name,mkdir
command to create a directory.
Command execution result:
We can tree
verify whether you have created a directory has been created.
$ tree -d
Copy files to multiple locations
We can use the xargs
command 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 xargs
time only one of the parameters passed to the command being used.
Want to call cp
twice each using one of the two directories as command line arguments, we can be xargs
of -n
1 to implement (max number) option is set.
There is also used -v
(verbose details) option, so that cp
operation 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. cp
The 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), xargs
these file names will not be interpreted correctly. We can use the -0
(null terminator) option to solve this problem. In this case, xargs
the use null
of characters as the file name of the final delimiter.
Here we find
command as an example. find
There 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” :
find
Search for objects whose name matches *.png from the current directory, andtype -f
specify to search only for files. - -print0 : The name will end with a null character, and spaces and special characters are reserved.
- xargs -0 :
xargs
It 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 "{}" :
rm
feedback 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 tree
to 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 xargs
passed 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 d
specifies the directory to find, not the file.
The name of each directory is printed out when deleted. We can tree
check the effect again:
$ tree -d
All nested subdirectories have been deleted.
Delete all files except one file type
We can use find
, xargs
and rm
delete 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.
-not
Options allow find
the return of all the search pattern does not match the file name. At this point we again use xargs
the -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 ls
to confirm the results. We can see, the directory and only the *.sh
files that match.
$ ls -l
Use Xargs to create compressed files
We can use the find
command to search for files by xargs
file name passed to the tar
command to create a compressed file.
We will search in the current directory * .sh
files.
$ 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: