xargs
Xargs is a command which can pass arguments from the output of one command to another. It can run multiline commands by passing arguments in a single file. The most important feature is that it creates a list of arguments to be passed to the command and runs them.
Example1)
Consider that you have many files and each have to be renamed with a common subscript letter.
/home/Krishna $ ls account_[0-9].txt
account_4
account_5
account_7
…
…
Then to rename all these files as < filename>_old , use xargs as follows.
/home/Krishna$ ls account_[0-9].txt | xargs -I { } mv { } { }_prev
/home/Krishna $ls account_[0-9]*
account_4_prev
account_5_prev
account_7_prev
..
Here, xargs passed the output of ls, which is a list as an argument list which is denoted by
‘{ }’ to the mv command .the the entire line can be reconstructed as
mv account_4 account_4_prev
mv account_5 account_5_prev
….
..
Example2)
On few occasions, many unwanted processes of a common type may be running and it is necessary to kill all of them without killing any other process. One method would be to kill all of them with their individual PIDs, but it may be not possible to do this in scripts, xargs does the job.
When it is required to kill all processes run by your login name that have names containing ftp in it,use
ps -fu $LOGNAME | grep ftp | awk ‘{ print $2 }’ | xargs -I { } kill -9 { }
Example 3)
You want to copy a large number of files into a directory placing all the filenames in a list file.
Consider a file containing list of all the filenames .end line contains the destination directory
/home/Krishna$ cat candidates_logs.txt
Arjuna.log
Yudhistir.log
Bhim.log
Nakul.log
Sahadev.log
…
..
/var/tmp/logs
You want to copy all these files to a directory /var/tmp/logs with timestamp. use xargs as follows.
/home/Krishna$ xargs cp –p < candidates_logs.txt
The command structure created by xargs was
cp -p Arjuna.log Yudhistir.log Bhim.log Nakul.log Sahadev.log … candidates_logs.txt
This avoided the typing of all the files in an entire line. You may use this form of xargs in scripts where it is easier to make the list file using simple echo and “>>” .
Example 4)
You are redirecting output containing contents of a file to another and you want a delimiting character after every n words , where n is any natural number, use xargs as follows.
a point to note here is that a word can be a single line if it contains only one word per line.
/home/Krishna$ cat Train-Time.list
S29 F 12 Mumbai_CST Karjat 7:00pm
T113 F 12 (x) Mumbai_CST Thane 7:04pm
K95 S 9 (x) Mumbai_CST Kalyan 7:06pm
A59 S 9 Mumbai_CST Ambernath 7:15pm
BL39 F 12 Mumbai_CST Badlapur 7:17pm
T115 S 9 (x) Mumbai_CST Thane 7:20pm
N27 F 12 Mumbai_CST Kalyan 7:21pm
You can use awk to delimit the fields with a “|” or any other delimiting character, but xargs can perform it too.
/home/Krishna$ cat Train-Time.list | xargs –n1 | xargs -I { } echo “{ }|”
S29| F| 12| Mumbai_CST| Karjat| 7:00pm|
T113| F| 12| Mumbai_CST| Thane| 7:04pm|
K95| S| 9| Mumbai_CST| Kalyan| 7:06pm|
A59| S| 9| Mumbai_CST| Ambernath 7:15pm|
BL39| F| 12| Mumbai_CST| Badlapur| 7:17pm|
T115| S| 9| Mumbai_CST| Thane| 7:20pm|
N27| F| 12| Mumbai_CST| Kalyan| 7:21pm|
You can trim the ending “|” character by using sed .
Here you could have also used values greater than 1 after n so that the character “|” might be inserted after those many words instead of 1.
Example 5)
When running commands by passing multiple arguments , it sometimes becomes necessary to interactively ask you to run it for each argument as seen in the commands cp -i and mv -i.
xargs using its -p option, can perform this on any command you want to run interactively.
Consider a case where you need to take tar of files in a directory by adding every file interactively into the archive file.
/home/Krishna$ ls | xargs -p -n 1 tar -cvf /backup/ALL_KRISHNA.tar
tar -cvf /backup/ALL_KRISHNA.tar account_4_prev ?...y
tar -cvf /backup/ALL_KRISHNA.tar account_5_prev ?...y
tar -cvf /backup/ALL_KRISHNA.tar account_7_prev ?...n ----------> your reply.
tar -cvf /backup/ALL_KRISHNA.tar jokes_old ?...y
..
..