قالب وردپرس درنا توس
Home / Tips and Tricks / Using the xargs command on Linux

Using the xargs command on Linux



  A Linux Terminal Command Prompt on a Laptop
Fatmawati Achmad Zaenuri / Shutterstock

Do some Linux commands have to be strung together, but one of them does not accept pipe input? xargs can send the output of a command as a parameter to another command.

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

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

One of the outstanding features of Linux and Unix-like operating systems is the ability to redirect the stdout output of a command to the stdin input of a second command. The first command does not care that the output does not go into a terminal window, and the second command does not care that the input does not come from a keyboard.

Although all Linux commands are tri-standard Not all of them accept the standard output of any other command as input to standard output. This means you can not pipe input.

xargs is a command to build execution pipelines using the default data streams. With xargs commands such as echo rm and mkdir can accept standard input arguments.

The xargs command

xargs accepts pipe input. It can also accept input from a file. xargs uses this input as a parameter for the commands it should work with. If we do not instruct xargs to work with a particular command, by default echo is used.

This allows us to demonstrate how xargs always works Create a single line of output, even from multi-line input.

If you use the option -1

(list one file per line) with ls you will get a single column of filenames.

  ls -1 ./*.sh[19659014)inaterminalwindow" width="646" height="57" src="/pagespeed_static/1.JiBnMqyl6S.gif" onload="pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);" onerror="this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);"/> 

Lists the shell script files in the current directory.

 Issue of ls in a terminal window

We expect to get a single column. If we direct 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.

 xargs in a terminal window are passed through.

This is the function that lets us feed xargs parameters into other commands.

Using xargs with wc

With xargs we wc can simply count the words and characters and include lines in multiple files.

  ls * .page | xargs wc 

  ls * .page | xargs wc in a terminal window

The following happens:

  • ls lists the * .page files and passes the list to xargs .
  • xargs Returns the filenames to wc .
  • wc treats the file names as if they were received as command line parameters.

  wc output in a terminal window

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

Using Xargs with Acknowledgment

With the option -p (interactive) you can ask Xargs to confirm that we are happy that it continues.

When we pass a series of filenames to touch xargs creates the files for us.

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

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

The command to execute appears and xargs waits for us to respond by typing "y" or "Y" or "n" "Or" N "and press Enter.

Pressing Enter only will treat this as" n. "The command will only be executed if you enter" y "or" Y. "

 xargs asks for confirmation in a terminal window

We pressed "y" and hit Enter We can check ls if the files were created.

  ls one two three [19659043] Issue of ls in a terminal window " width="646" height="132" src="/pagespeed_static/1.JiBnMqyl6S.gif" onload="pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);" onerror="this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);"/> 

Using xargs with multiple commands

We can use xargs multiple commands by using the option -I ( Initial arguments).

This option defines a "replacement character foo lge ", wherever the token represents the replacement character. The command line displays a string. The values ​​passed to xargs are inserted.

Use the tree command to display the subdirectories of the current directory. The option -d (directory) causes the -tree files to be ignored and only directories to be reported.

  tree -d 

  tree -d in a terminal window

There is a single subdirectory named "images".

In a file called "directory.txt" we have the names of some directories that we want to create. We can view the content with cat .

  cat directory.txt 

  cat directory.txt in a terminal window

We will use this as input data for xargs . The command we are running now is:

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

This works as follows:

  • cat directory.txt | : This moves the contents of the directrories.txt file (all new directory names) to xargs .
  • xargs -I% : Defines a "replacement string" with the token "%".
  • sh -c : Launches a new subshell. The -c command instructs the shell to read commands from the command line.
  • 'echo%; mkdir% ': Each of the% tokens is replaced by the directory names passed by xargs . The command echo returns the directory name. The directory is created with the command mkdir .

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

The directories are listed one after the other.

 Issue of xargs in a terminal window

We can use tree . again to check if the directories were created.

  tree -d 

 Outputting tree in a terminal window

Copying files to multiple locations

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

We pass the names of two directories as input parameters to xargs . We instruct xargs to pass only one of these parameters to the command it is working with.

In this case, the command is cp . The effect is to invoke cp twice, each time using one of the two directories as a command-line parameter. The parameter xargs that allows this is the option -n (maximum number). We will set this to one.

We also use the option -v (verbose) with cp to report what happens. [19659013] echo ~ / Backups / ~ / Documents / page-files / | xargs -n 1 cp -v ./*.page[19659056[19459056[echo~/backups/~/documents/page-files/|xargs-n1cp-v/*pageinaterminalwindow" width="646" height="77" src="/pagespeed_static/1.JiBnMqyl6S.gif" onload="pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);" onerror="this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);"/>

The files are stored in copied two directories. cp reports each file copy action so we can see how it is executed.

 xargs and cp output in a terminal window

deleting files in nested directories

If filenames contain spaces and strange characters (such as newlines), they can be used by xargs can not be interpreted correctly. We can fix this problem by using the option -0 (null terminator). This instructs xargs to use the null character as the final filename separator.

This example uses find . find has its own option to handle spaces and strange characters in filenames. It is the option -print0 (full name, null character).

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

This breaks down as follows:

  • find. -name "* .png" : find searches from the current directory "." for objects with names that match "* .png" and are files ( type -f ).
  • -print0 : Names are terminated with a null character, spaces and special characters are taken into account.
  • xargs -0 : xargs will also regard filenames as null-terminated, and spaces and strange characters do not cause problems.
  • rm -v -rf "{}" : rm will be detailed and report what happens ( -v ). It is recursive (-r) and searches nested subdirectories and removes files without prompting ( -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 pattern are deleted.

 Output of rm in a terminal window

Remove nested directories

Suppose we want to remove a number of nested subdirectories. Tree we will let her see.

  Tree -d 

 Find tree -d in a terminal window

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

This command uses find to search recursively in the current directory. The search target is a directory named "level_one". The directory names are passed through 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: The search term is the name of the top directory and . -type d instructs find to search for directories, not files.

 Output of find and xargs and rm in a terminal window.

The name of each directory is printed when it is removed. We can check with tree :

  tree -d 

 tree -d in a terminal window

All nested subdirectories are deleted.

Delete All Files Except for a File Type

With find xargs and rm you can delete all files except a file type that you want to keep. It is a bit inexplicable, but we give the name of the file type we want to keep not the name of the file to be deleted.

The option -not splits [19459009mit] find to return the names of files that do not match the search pattern. We use the option -I (first arguments) again with xargs . This time, the replacement string token we defined is "{}". This is the same as the previously generated replacement string token, which happens to be 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 this with ls . The directory contains only files that match the search pattern "* .sh".

  ls -l 

 Output of ls in a terminal window

Creating an archive file With Xargs

we can search for files with find and use this xargs to tar to create an archive file.

We & # 39; It is searched in the current directory. The search pattern is "* .page", so we search 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 framework to stack things together. xargs bridges the gap between commands that can pump out information and commands that are not created for it.

Both xargs and find a large number of options. We recommend that you read the man pages for more information.




Source link