xargs是一條Unix和類Unix作業系統的常用指令。它的作用是将參數清單轉換成小塊分段傳遞給其他指令,以避免參數清單過長的問題;将多行輸入轉換為單行 (特殊功效)
xargs [-0prtx] [-E eof-str] [-e[eof-str]] [--eof[=eof-str]] [--null]
[-d delimiter] [--delimiter delimiter] [-I replace-str] [-i[replace-
str]] [--replace[=replace-str]] [-l[max-lines]] [-L max-lines]
[--max-lines[=max-lines]] [-n max-args] [--max-args=max-args] [-s max-
chars] [--max-chars=max-chars] [-P max-procs] [--max-procs=max-procs]
[--interactive] [--verbose] [--exit] [--no-run-if-empty]
[--arg-file=file] [--show-limits] [--version] [--help] [command
[initial-arguments]]
xargs一般是和管道一起使用,選項:
-p 操作具有可互動性,每次執行comand都互動式提示使用者選擇
-i 告訴 xargs 可以使用{}代替傳遞過來的參數, 建議使用-I,其符合POSIX标準
-I 格式: xargs -I rep-str comand rep-srt
rep-str 為代替傳遞給xargs參數, 可以使 {} $ @ 等符号 ,其主要作用是當xargs command 後有多個參數時,調整參數位置。例如:
<code>find . -name </code><code>"*.txt "</code> <code>|xargs -I {} cp {} /tmp</code>
-t 啟用指令行輸出模式:其先回顯要運作的指令,然後執行指令,列印出指令結果,跟蹤與調試xargs的利器,也是研究xargs運作原理的好辦法;
-r 如果沒有要處理的參數傳遞給xargs,xargs 預設是帶空參數運作一次,如果你希望無參數時,停止 xargs,直接退出,使用 -r 選項即可,其可以防止xargs 後面指令帶空參數運作報錯。
-s size 設定每次構造Command行的長度總大小,包括 command +init-param +傳遞參數,Size 參數必須是正整數
-n 控制每次輸入的參數個數,參數以空白字元或<newline>換行符分割,-L 和 -n 标志是互相排斥的;最後指定的标志生效。
-L num 參數控制每次輸入的行數 ,-l和-L功能一樣,不建議使用。
-t 參數,打開調試功能,顯示每次所組的指令,在調試中非常有用,可以看出xargs的執行原理
-x 如果有任何 Command 行大于 -s Size 标志指定的位元組數,停止運作 xargs 指令,-L -I -n 預設打開-x參數
<code>#cat t.txt </code>
<code> </code><code>tata-hi -fuck - ok </code>
<code> </code><code>fuck _you _ you </code>
<code>#xargs -a t.txt -E _ </code>
<code> </code><code>tata-hi -fuck - ok fuck _you </code>
<code>#xargs -a t.txt -E - </code>
<code> </code><code>tata-hi -fuck</code>
-r xargs 預設是空參數comand也要執行一次,如使用-r參數遇到空參數則直接退出,不會再執行一次,避免程式執行錯誤。
<code>#ls |grep Tata </code>
<code>#ls |grep Tata |xargs -t </code>
<code>/bin/echo </code>
<code> </code>
<code>#ls |grep Tata |xargs -t -r</code>
find -print 和 -print0的差別:
-print 在每一個輸出後會添加一個回車換行符,而-print0則不會。
執行個體:
如果path目錄下檔案過多就會因為“參數清單過長”而報錯無法執行。但改用xargs以後,問題即獲解決。
<code>rm `find /path -type f`</code>
本例中xargs将find産生的長串檔案清單拆散成多個子串,然後對每個子串調用rm。-print0表示輸出以null分隔(-print使用換行);-0表示輸入以null分隔。
<code>find /path -type f -print0 | xargs -</code><code>0</code> <code>rm</code>
這樣要比如下使用find指令效率高的多。
<code>find /path -type f -exec rm </code><code>'{}'</code> <code>\;</code>
xargs指令應該緊跟在管道操作符之後,它以标準輸入作為主要的源資料流,并使用stdin并通過提供指令行參數來執行其他指令,例如:
<code>command | xargs</code>
執行個體應用1,将多行輸入轉換為單行輸出:
<code>$ cat example.txt </code>
<code>1</code> <code>2</code> <code>3</code> <code>4</code> <code>5</code>
<code>6</code> <code>7</code>
<code>8</code>
<code>$ cat example.txt | xargs </code>
<code>1</code> <code>2</code> <code>3</code> <code>4</code> <code>5</code> <code>6</code> <code>7</code> <code>8</code>
執行個體應用2,将單行輸入轉換為多行輸出:
<code>$ cat example.txt | xargs -n </code><code>2</code>
<code>1</code> <code>2</code>
<code>3</code> <code>4</code>
<code>5</code> <code>6</code>
<code>7</code> <code>8</code>
空格是預設的定界符,-n 表示每行顯示幾個參數
還可以使用-d參數來分隔參數,如下:
<code>$ echo </code><code>"splitXhiXamosliXsplit"</code> <code>| xargs -d </code><code>"X"</code> <code>-n </code><code>1</code>
<code>split</code>
<code>hi</code>
<code>amosli</code>
執行個體應用3,讀取stdin,将格式化參數傳遞給指令
#定義一個echo指令每次在輸出參數後都加上#
<code>$ cat cecho.sh </code>
<code>echo $*</code><code>'#'</code>
#需求1:輸出多個參數
<code>$ sh cecho.sh arg1 </code>
<code>arg1#</code>
<code>$ sh cecho.sh arg2 </code>
<code>arg2#</code>
<code>$ sh cecho.sh arg3 </code>
<code>arg3#</code>
#需求2:一次性提供所有的指令參數
<code>$ sh cecho.sh arg1 arg2 arg3</code>
<code>arg1 arg1 arg2 arg3#</code>
#針對需求1、2,使用xargs代替,先用vi建一個新檔案args.txt,如下:
<code>$ cat args.txt </code>
<code>arg1</code>
<code>arg2</code>
<code>arg3</code>
#批量輸出參數:
<code>$ cat args.txt | xargs -n </code><code>1</code>
<code>$ cat args.txt | xargs -n </code><code>2</code> <code>sh cecho.sh</code>
<code>arg1 arg2#</code>
#一次性輸出所有參數:
<code>$ cat args.txt | xargs sh cecho.sh ;</code>
<code>arg1 arg2 arg3#</code>
需求3,如何将參數嵌入到固定的指令行中?如下所示:
<code>$ sh cecho.sh -p args1 -</code><code>1</code>
<code>-p args1 -</code><code>1</code><code>#</code>
<code>$ sh cecho.sh -p args2 -</code><code>1</code>
<code>-p args2 -</code><code>1</code><code>#</code>
<code>$ sh cecho.sh -p args3 -</code><code>1</code>
<code>-p args3 -</code><code>1</code><code>#</code>
使用xargs的解決方案:
<code>$ cat args.txt | xargs -I {} sh cecho.sh -p {} -</code><code>1</code>
<code>-p arg1 -</code><code>1</code><code>#</code>
<code>-p arg2 -</code><code>1</code><code>#</code>
<code>-p arg3 -</code><code>1</code><code>#</code>
#-I {}批定了替換字元串,字元串{}會被從stdin讀取到的參數所替換,使用-I時,能循環按要求替換相應的參數
執行個體應用4,結合find使用xargs
前面已經舉過例子,這裡要注意的是檔案名稱定界符要以字元null來分隔輸出,如下所示,否則可能會誤删檔案代碼如下:
<code>$ find . -type f -name </code><code>"*test*.txt"</code> <code>-print0 | xargs -</code><code>0</code> <code>rm -f</code>
其他:
假如你有一個檔案包含了很多你希望下載下傳的URL, 你能夠使用xargs 下載下傳所有連結
cat url-list.txt | xargs wget –c
查找所有的jpg 檔案,并且壓縮它
find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz
拷貝所有的圖檔檔案到一個外部的硬碟驅動
ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory
args結合sed替換:
find . -name "*.txt" -print0 | xargs -0 sed -i 's/aaa/bbb/g'
xargs結合grep:
find . -name '*.txt' -type f -print0 |xargs -0 grep -n 'aaa' #“-n”輸出行号
cat file |(while read a;do echo $a;done)
cat file |xargs -I {} cat {}
本文轉自奔跑在路上部落格51CTO部落格,原文連結http://blog.51cto.com/qiangsh/1868476如需轉載請自行聯系原作者
qianghong000