天天看點

linux下xargs指令詳解和執行個體

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 控制每次輸入的參數個數,參數以空白字元或&lt;newline&gt;換行符分割,-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

繼續閱讀