xargs是一條Unix和類Unix作業系統的常用命令。它的作用是將引數列表轉換成小塊分段傳遞給其他命令,以避免引數列表過長的問題。
例如,下面的命令:
rm `find /path -type f`
如果path目錄下檔案過多就會因為“引數列表過長”而報錯無法執行。但改用xargs以後,問題即獲解決。
find /path -type f -print0 | xargs -0 rm
本例中xargs將find產生的長串檔案列表拆散成多個子串,然後對每個子串呼叫rm。-print0表示輸出以null分隔(-print使用換行);-0表示輸入以null分隔。這樣要比如下使用find命令效率高的多。
find /path -type f -exec rm '{}' \;
xargs命令應該緊跟在管道操作符之後,它以標準輸入作為主要的源資料流,並使用stdin並通過提供命令列引數來執行其他命令,例如:
command | xargs
例項應用1,將多行輸入轉換為單行輸出:
amosli@amosli-pc:~/learn$ cat example.txt 1 2 3 4 5 6 7 8
amosli@amosli-pc:~/learn$ cat example.txt | xargs 1 2 3 4 5 6 7 8
例項應用2,將單行輸入轉換為多行輸出:
amosli@amosli-pc:~/learn$ cat example.txt | xargs -n 2 1 2 3 4 5 6 7 8
空格是預設的定界符,-n 表示每行顯示幾個引數
還可以使用-d引數來分隔引數,如下:
amosli@amosli-pc:~/learn$ echo "splitXhiXamosliXsplit" | xargs -d "X" -n 1 split hi amosli split
例項應用3,讀取stdin,將格式化引數傳遞給命令
#定義一個echo命令每次在輸出引數後都加上# amosli@amosli-pc:~/learn$ cat cecho.sh echo $*'#' #需求1:輸出多個引數 amosli@amosli-pc:~/learn$ sh cecho.sh arg1 arg1# amosli@amosli-pc:~/learn$ sh cecho.sh arg2 arg2# amosli@amosli-pc:~/learn$ sh cecho.sh arg3 arg3# #需求2:一次性提供所有的命令引數 amosli@amosli-pc:~/learn$ sh cecho.sh arg1 arg2 arg3 arg1 arg1 arg2 arg3# #針對需求1、2,使用xargs代替,先用vi建一個新檔案args.txt,如下: amosli@amosli-pc:~/learn$ cat args.txt arg1 arg2 arg3 #批量輸出引數: amosli@amosli-pc:~/learn$ cat args.txt | xargs -n 1 arg1 arg2 arg3 amosli@amosli-pc:~/learn$ cat args.txt | xargs -n 2 sh cecho.sh arg1 arg2# arg3# #一次性輸出所有引數: amosli@amosli-pc:~/learn$ cat args.txt | xargs sh cecho.sh ; arg1 arg2 arg3#
需求3,如何將引數嵌入到固定的命令列中?如下所示:
amosli@amosli-pc:~/learn$ sh cecho.sh -p args1 -1 -p args1 -1# amosli@amosli-pc:~/learn$ sh cecho.sh -p args2 -1 -p args2 -1# amosli@amosli-pc:~/learn$ sh cecho.sh -p args3 -1 -p args3 -1#
使用xargs的解決方案:
amosli@amosli-pc:~/learn$ cat args.txt | xargs -I {} sh cecho.sh -p {} -1 -p arg1 -1# -p arg2 -1# -p arg3 -1# #-I {}批定了替換字串,字串{}會被從stdin讀取到的引數所替換,使用-I時,能迴圈按要求替換相應的引數
例項應用4,結合find使用xargs
前面已經舉過例子,這裡要注意的是檔名稱定界符要以字元null來分隔輸出,如下所示,否則可能會誤刪檔案
amosli@amosli-pc:~/learn$ find . -type f -name "*test*.txt" -print0 | xargs -0 rm -f
其他:
cat file | ( while read arg; do cat $arg; done ) cat file | xargs -I {} cat {}