xargs [ -p ] [ -t ] [ -e [ EOFString ] ] [ -E EOFString ] [ -i [ ReplaceString ] ] [ -I ReplaceString ] [ -l [ Number ] ] [ -L Number ] [ -n Number [ -x ] ] [ -s Size ] [ Command [ Argument ... ] ] 注: 不要在小寫的符號和參數(shù)之間加空格,。 xargs 可以讀入 stdin 的資料,并且以空白字符或換行符作分隔,,將 stdin 的資料分隔成為 arguments ,。因?yàn)槭且钥瞻鬃址鳛榉指簦?,如果有一些文件名或者是其他意義的名詞內(nèi)含有空白字符的時候,, xargs 可能會誤判。,! 參數(shù)∶ -0 ∶如果輸入的 stdin 含有特殊字符,,例如 `, \, 空白鍵等等字元時,這個 -0 參數(shù)可以將他還原成一般字元,。這個參數(shù)可以用于特殊狀態(tài)喔,! -e ∶這個是 EOF (end of file) 的意思。后面可以接一個字串,,當(dāng) xargs 分析到這個字串時,,就會停止繼續(xù)工作! -p ∶在執(zhí)行每個指令的 argument 時,,都會詢問使用者的意思,; -n ∶后面接次數(shù),每次 command 指令執(zhí)行時,,要使用幾個參數(shù)的意思,。看范例三,。 當(dāng) xargs 后面沒有接任何的指令時,,預(yù)設(shè)是以 echo 來進(jìn)行輸出喔! 范例∶ 范例一∶將 /etc/passwd 內(nèi)的第一欄取出,,僅取三行,,使用 finger 這個指令將每個賬號內(nèi)容秀出來 [root@linux ~]# cut -d':' -f1 < /etc/passwd |head -n 3| xargs finger Login: root Name: root Directory: /root Shell: /bin/bash Never logged in. No mail. No Plan. ......底下省略..... # 由 finger account 可以取得該賬號的相關(guān)說明內(nèi)容,例如上面的輸出就是 finger root后的結(jié)果,。在這個例子當(dāng)中,,我們利用 cut 取出賬號名稱,用 head 取出三個賬號,,最后則是由 xargs 將三個賬號的名稱變成 finger 后面需要的參數(shù),! 范例二∶同上,但是每次執(zhí)行 finger 時,都要詢問使用者是否動作,? [root@linux ~]# cut -d':' -f1 < /etc/passwd |head -n 3| xargs -p finger finger root bin daemon ?...y ......底下省略..... # 呵呵,!這個 -p 的參數(shù)有趣了吧?,!他可以讓使用者的使用過程中,,被詢問到每個指令是否執(zhí)行! 范例三∶將所有的 /etc/passwd 內(nèi)的賬號都以 finger 查閱,,但一次僅查閱五個賬號 [root@linux ~]# cut -d':' -f1 < /etc/passwd | xargs -p -n 5 finger finger root bin daemon adm lp ?...y ......底下省略..... # 在這里鳥哥使用了 -p 這個參數(shù)來讓您對于 -n 更有概念,。一般來說,某些指令后面可以接的 arguments 是有限制的,,不能無限制的累加,,此時,我們可以利用 -n來幫助我們將參數(shù)分成數(shù)個部分,,每個部分分別再以指令來執(zhí)行,!這樣就 OK 啦!^_^ [root@linux ~]# 范例四∶同上,,但是當(dāng)分析到 lp 就結(jié)束這串指令,? [root@linux ~]# cut -d':' -f1 < /etc/passwd | xargs -p -e'lp' finger finger root bin daemon adm ?... # 仔細(xì)與上面的案例做比較。也同時注意,,那個 -e'lp' 是連在一起的,,中間沒有空白鍵。 # 上個例子當(dāng)中,,第五個參數(shù)是 lp 啊,,那么我們下達(dá) -e'lp' 后,則分析到 lp這個字串時,,后面的其他 stdin 的內(nèi)容就會被 xargs 舍棄掉了,! find . -name '*.py' | xargs wc -l 遞歸查找所有Emacs備份文件并刪除: find . -name '*~' | xargs rm 遞歸查找所有Python文件并搜索import語句: find . -name '*.py' | xargs grep 'import' 處理文件/目錄名中的空格 上面的例子有一個問題,如果文件或是目錄名含有空格,,則可能會有些問題,,這是因?yàn)閤args默認(rèn)會按照空白字符來劃分輸入。一個簡單的解決辦法就是告訴find使用NUL(\0)來分割結(jié)果(通過向find提供-print0選項(xiàng)),,并且告訴xargs也使用Nul來分隔輸入(-0),。 刪除備份文件,即使含有空格: find . -name '*~' -print0 | xargs -0 rm 參數(shù)位置 上面的例子中xargs從標(biāo)準(zhǔn)輸入讀取所有非空的元素并將他們連接起來提供給給定的命令進(jìn)行執(zhí)行,,這在很多情況下會非常有用,,盡管如此,有時你可能想要在命令中間插入一個參數(shù),,此時-J標(biāo)記就排上用場了,,xargs會為-J參數(shù)后面的字符串加上輸入然后再執(zhí)行,。 將所有備份文件復(fù)制到backups目錄下: find . -name '*~' -print 0 | xargs -0 -J % cp % ~/backups 最大命令長度 有時通過管道傳遞給xargs的輸入可能會造成要執(zhí)行的命令超出最大命令行長度限制,你可以通過下面的命令得到命令行的最大長度: getconf ARG_MAX 為了避免越限,,xargs對于結(jié)果命令有它自己的最大長度限制,,如果提供的參數(shù)有可能會造成調(diào)用的命令超出長度限制,,則xargs會將輸入分割成多個部分,,并多次調(diào)用目標(biāo)命令,默認(rèn)的長度限制是4096,,這可能要遠(yuǎn)遠(yuǎn)小于大多數(shù)現(xiàn)在系統(tǒng)的ARG_MAX設(shè)置,,你可以通過向xargs提供-s標(biāo)識來覆蓋這個默認(rèn)設(shè)置,當(dāng)你對一個很大的源代碼倉庫進(jìn)行操作時,,這會顯得尤其有用,。 指定參數(shù)數(shù)量 如果你要執(zhí)行的命令只接受1個或是2個參數(shù),比如使用diff命令來對2個文件進(jìn)行比較,,那么xargs的-n選項(xiàng)就會非常有用,,它可以指定一次向目標(biāo)命令提供幾個參數(shù),如果參數(shù)數(shù)量多于你制定的數(shù)量,,則命令將會被重復(fù)調(diào)用,,直到所有輸入都已經(jīng)得到執(zhí)行。注意,,最后一次調(diào)用的參數(shù)有可能會少于指定的參數(shù)數(shù)量,,下面讓我們來看一個簡單的例子: $ echo {0..9} | xargs -n 2 0 1 2 3 4 5 6 7 8 9 同樣的,你也可以使用-L參數(shù)制定每次只對某幾行的輸入進(jìn)行操作,,比如-L 1將每次從輸入中取一行作為參數(shù)傳遞給待執(zhí)行的命令,,當(dāng)然,你可以將1改為任意行,,但1是最常用的,,下面這條命令將演示如何得到每個git commit的代碼變化: git log --format="%H %P" | xargs -L 1 git diff 并行執(zhí)行命令 你或許會使用xargs調(diào)用某些需要密集計(jì)算的命令,如果xargs可以利用你電腦上的多核計(jì)算能力,,那該有多美妙,?沒錯,-P參數(shù)就是干這個的,,通過這個參數(shù)xargs可以一次并行的調(diào)用多個命令,,舉個例子,你可以通過它來并行的運(yùn)行多個ffmpeg編碼器,,不過,,還是讓我們來個更簡單一點(diǎn)的例子吧: 并行休眠 $ time echo {1..5} | xargs -n 1 -P 5 sleep real 0m5.013s user 0m0.003s sys 0m0.014s 線性休眠 $ time echo {1..5} | xargs -n 1 sleep real 0m15.022s user 0m0.004s sys 0m0.015s 如果你對使用xargs進(jìn)行并行計(jì)算感興趣,那么你或許應(yīng)該看看GNU parallel,,相比較而言,,xargs的優(yōu)勢就是大多數(shù)系統(tǒng)默認(rèn)都支持它,,并且在BSD和OS X上也可以很容易的安裝,但是parallel則有許多非常贊的特性,。 僅對上文FIND用法進(jìn)行補(bǔ)充.完全看不懂,只有最下面一句能用得到: xargs 大多數(shù) Linux 命令都會產(chǎn)生輸出:文件列表,、字符串列表等。但如果要使用其他某個命令并將前一個命令的輸出作為參數(shù)該怎么辦,?例如,,file 命令顯示文件類型(可執(zhí)行文件、ascii 文本等),;您可以處理輸出,,使其僅顯示文件名,現(xiàn)在您希望將這些名稱傳遞給 ls -l 命令以查看時間戳記,。xargs 命令就是用來完成此項(xiàng)工作的,。它允許您對輸出執(zhí)行其他某些命令。 xargs – build and execute command lines from standard input 在使用find命令的-exec選項(xiàng)處理匹配到的文件時,, find命令將所有匹配到的文件一起傳遞給exec執(zhí)行,。但有些系統(tǒng)對能夠傳遞給exec的命令長度有限制,這樣在find命令運(yùn)行幾分鐘之后,,就會出現(xiàn)溢出錯誤,。錯誤信息通常是“參數(shù)列太長”或“參數(shù)列溢出”。這就是xargs命令的用處所在,,特別是與find命令一起使用,。 記住下面這個來自于第 1 部分中的語法: file -Lz * | grep ASCII | cut -d":” -f1 | xargs ls -ltr 讓我們來剖析這個命令字符串。第一個,,file -Lz *,,用于查找是符號鏈接或者經(jīng)過壓縮的文件。它將輸出傳遞給下一個命令 grep ASCII,,該命令在其中搜索 “ASCII” 字符串并產(chǎn)生如下所示的輸出: alert_DBA102.log: ASCII English text alert_DBA102.log.Z: ASCII text (compress’d data 16 bits) dba102_asmb_12307.trc.Z: ASCII English text (compress’d data 16 bits) dba102_asmb_20653.trc.Z: ASCII English text (compress’d data 16 bits) 由于我們只對文件名感興趣,,因此我們應(yīng)用下一個命令 cut -d”:” -f1,僅顯示第一個字段: alert_DBA102.log alert_DBA102.log.Z dba102_asmb_12307.trc.Z dba102_asmb_20653.trc.Z 現(xiàn)在,,我們希望使用 ls -l 命令,,將上述列表作為參數(shù)進(jìn)行傳遞,一次傳遞一個,。xargs 命令允許您這樣做,。最后一部分,xargs ls -ltr,,用于接收輸出并對其執(zhí)行 ls -ltr 命令,,如下所示: ls -ltr alert_DBA102.log ls -ltr alert_DBA102.log.Z ls -ltr dba102_asmb_12307.trc.Z ls -ltr dba102_asmb_20653.trc.Z 因此,xargs 本身雖然沒有多大用處,,但在與其他命令相結(jié)合時,,它的功能非常強(qiáng)大,。 下面是另一個示例,我們希望計(jì)算這些文件中的行數(shù): $ file * | grep ASCII | cut -d”:” -f1 | xargs wc -l 47853 alert_DBA102.log 19 dba102_cjq0_14493.trc 29053 dba102_mmnl_14497.trc 154 dba102_reco_14491.trc 43 dba102_rvwr_14518.trc 77122 total (注:上述任務(wù)還可用以下命令完成:) $ wc -l ‘file * | grep ASCII | cut -d”:” -f1 | grep ASCII | cut -d”:” -f1‘ 該 xargs 版本用于闡釋概念,。Linux 可以用幾種方法來完成同一個任務(wù),;請使用最適合您的情況的方法。 使用該方法,,您可以快速重命名目錄中的文件,。 $ ls | xargs -t -i mv {} {}.bak -i 選項(xiàng)告訴 xargs 用每項(xiàng)的名稱替換 {}。-t 選項(xiàng)指示 xargs 先打印命令,,然后再執(zhí)行,。 另一個非常有用的操作是當(dāng)您使用 vi 打開要編輯的文件時: $ file * | grep ASCII | cut -d”:” -f1 | xargs vi 該命令使用 vi 逐個打開文件。當(dāng)您希望搜索多個文件并打開它們進(jìn)行編輯時,,使用該命令非常方便。 它還有幾個選項(xiàng),。最有用的可能是 -p 選項(xiàng),,它使操作具有可交互性: $ file * | grep ASCII | cut -d”:” -f1 | xargs -p vi vi alert_DBA102.log dba102_cjq0_14493.trc dba102_mmnl_14497.trc dba102_reco_14491.trc dba102_rvwr_14518.trc ?… 此處的 xarg 要求您在運(yùn)行每個命令之前進(jìn)行確認(rèn)。如果您按下 “y”,,則執(zhí)行命令,。當(dāng)您對文件進(jìn)行某些可能有破壞且不可恢復(fù)的操作(如刪除或覆蓋)時,您會發(fā)現(xiàn)該選項(xiàng)非常有用,。 -t 選項(xiàng)使用一個詳細(xì)模式,;它顯示要運(yùn)行的命令,是調(diào)試過程中一個非常有幫助的選項(xiàng),。 如果傳遞給 xargs 的輸出為空怎么辦,?考慮以下命令: $ file * | grep SSSSSS | cut -d”:” -f1 | xargs -t wc -l wc -l 0 $ 在此處,搜索 “SSSSSS” 后沒有匹配的內(nèi)容,;因此 xargs 的輸入均為空,,如第二行所示(由于我們使用 -t 這個詳細(xì)選項(xiàng)而產(chǎn)生的結(jié)果)。雖然這可能會有所幫助,,但在某些情況下,,如果沒有要處理的內(nèi)容,您可能希望停止 xargs,;如果是這樣,,可以使用 -r 選項(xiàng): $ file * | grep SSSSSS | cut -d”:” -f1 | xargs -t -r wc -l $ 如果沒有要運(yùn)行的內(nèi)容,該命令退出,。 假設(shè)您希望使用 rm 命令(該命令將作為 xargs 命令的參數(shù))刪除文件,。然而,rm 只能接受有限數(shù)量的參數(shù),。如果您的參數(shù)列表超出該限制怎么辦,?xargs 的 -n 選項(xiàng)限制單個命令行的參數(shù)個數(shù),。 下面顯示了如何限制每個命令行僅使用兩個參數(shù):即使向 xargs ls -ltr 傳遞五個文件,但每次向 ls -ltr 僅傳遞兩個文件,。 $ file * | grep ASCII | cut -d”:” -f1 | xargs -t -n2 ls -ltr ls -ltr alert_DBA102.log dba102_cjq0_14493.trc -rw-r—– 1 oracle dba 738 Aug 10 19:18 dba102_cjq0_14493.trc -rw-r–r– 1 oracle dba 2410225 Aug 13 05:31 alert_DBA102.log ls -ltr dba102_mmnl_14497.trc dba102_reco_14491.trc -rw-r—– 1 oracle dba 5386163 Aug 10 17:55 dba102_mmnl_14497.trc -rw-r—– 1 oracle dba 6808 Aug 13 05:21 dba102_reco_14491.trc ls -ltr dba102_rvwr_14518.trc -rw-r—– 1 oracle dba 2087 Aug 10 04:30 dba102_rvwr_14518.trc 使用該方法,,您可以快速重命名目錄中的文件。 $ ls | xargs -t -i mv {} {}.bak -i 選項(xiàng)告訴 xargs 用每項(xiàng)的名稱替換 {},。 我需要將一個用.svn管理的項(xiàng)目改成由CVS來管理,,因此,在導(dǎo)入整個項(xiàng)目到CVS中之前,,我需要刪除所有目錄下以及子孫目錄下的.svn目錄及.svn目錄下的的子目錄和文件,。我一直尋找一種最簡單的方法,最后寫了一個程序去干這事情,。結(jié)果同事告訴我只需要一條指令就可以了:find -name ‘.svn’ |xargs rm -rf 這個教訓(xùn)非常慘重,,我一生討厭傻瓜,可那一刻發(fā)現(xiàn)自己是最大的傻瓜,! 是的,,雖然我們——至少是我,天天使用LINUX但是真的是在高效的使用這個系統(tǒng)嗎,?不,,很多時候并沒有花時間去研究它,使用一些固有愚蠢的方式和思維模式在使用這個系統(tǒng),。 1. 建立多級目錄: mkidr 指令用來建立目錄,,事實(shí)上,我們一直都是這么干的,。但是在這么使用的時候我們并沒有去看它的那些參數(shù)提供了哪些額外的功能. mkidr -p /share/dragon ; 在根目錄下建立share目錄,,并在/share目錄下建立dragon目錄。mkdir -p guicmd/{bin,lib,src,share/version,doc/{html,pdf,info,man}} ;用來建立一個復(fù)雜的項(xiàng)目目錄樹,。 2.find 配合xargs使用: find -name ‘.svn’ |xargs rm -rf ;這個不用說了,,就是我前面提到的。 xargs更加象一個篩選器,,將符合管道傳遞過來的文件名的內(nèi)容一并處理掉,,這是一個極度高效的方法,。 三,、xargs xargs – build and execute command lines from standard input 在使用find命令的-exec選項(xiàng)處理匹配到的文件時,, find命令將所有匹配到的文件一起傳遞給exec執(zhí)行。但有些系統(tǒng)對能夠傳遞給exec的命令長度有限制,,這樣在find命令運(yùn)行幾分鐘之后,,就會出現(xiàn)溢出錯誤。錯誤信息通常是“參數(shù)列太長”或“參數(shù)列溢出”,。這就是xargs命令的用處所在,,特別是與find命令一起使用,。 find命令把匹配到的文件傳遞給xargs命令,而xargs命令每次只獲取一部分文件而不是全部,,不像-exec選項(xiàng)那樣,。這樣它可以先處理最先獲取的一部分文件,然后是下一批,,并如此繼續(xù)下去,。 在有些系統(tǒng)中,使用-exec選項(xiàng)會為處理每一個匹配到的文件而發(fā)起一個相應(yīng)的進(jìn)程,,并非將匹配到的文件全部作為參數(shù)一次執(zhí)行,;這樣在有些情況下就會出現(xiàn)進(jìn)程過多,系統(tǒng)性能下降的問題,,因而效率不高,; 而使用xargs命令則只有一個進(jìn)程。另外,,在使用xargs命令時,,究竟是一次獲取所有的參數(shù),還是分批取得參數(shù),,以及每一次獲取參數(shù)的數(shù)目都會根據(jù)該命令的選項(xiàng)及系統(tǒng)內(nèi)核中相應(yīng)的可調(diào)參數(shù)來確定。 來看看xargs命令是如何同find命令一起使用的,,并給出一些例子,。 下面的例子查找系統(tǒng)中的每一個普通文件,然后使用xargs命令來測試它們分別屬于哪類文件 #find . -type f -print | xargs file ./.kde/Autostart/Autorun.desktop: UTF-8 Unicode English text ./.kde/Autostart/.directory: ISO-8859 text\ ...... 在整個系統(tǒng)中查找內(nèi)存信息轉(zhuǎn)儲文件(core dump) ,,然后把結(jié)果保存到/tmp/core.log 文件中: $ find / -name "core" -print | xargs echo "" >/tmp/core.log 上面這個執(zhí)行太慢,,我改成在當(dāng)前目錄下查找 #find . -name "file*" -print | xargs echo "" > /temp/core.log # cat /temp/core.log ./file6 在當(dāng)前目錄下查找所有用戶具有讀、寫和執(zhí)行權(quán)限的文件,,并收回相應(yīng)的寫權(quán)限: <code># ls -l drwxrwxrwx 2 sam adm 4096 10月 30 20:14 file6 -rwxrwxrwx 2 sam adm 0 10月 31 01:01 http3.conf -rwxrwxrwx 2 sam adm 0 10月 31 01:01 httpd.conf # find . -perm -7 -print | xargs chmod o-w # ls -l drwxrwxr-x 2 sam adm 4096 10月 30 20:14 file6 -rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf -rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf 用grep命令在所有的普通文件中搜索hostname這個詞: # find . -type f -print | xargs grep "hostname" ./httpd1.conf:# different IP addresses or hostnames and have them handled by the ./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames on your 用grep命令在當(dāng)前目錄下的所有普通文件中搜索hostnames這個詞: # find . -name \* -type f -print | xargs grep "hostnames" ./httpd1.conf:# different IP addresses or hostnames and have them handled by the ./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames on your 注意,,在上面的例子中, \用來取消find命令中的*在shell中的特殊含義,。 find命令配合使用exec和xargs可以使用戶對所匹配到的文件執(zhí)行幾乎所有的命令,。 ============================================================ 打包操作系統(tǒng)里,所有.sh文件到abc.tar,。 1,、操作系統(tǒng)里所有.sh文件,find的時候目錄設(shè)定為"/",,不要用"./",。 2、打包整個操作系統(tǒng)的.sh文件,,一次性打包可能會因?yàn)槲募^多發(fā)生覆蓋,,建議設(shè)置xargs的-n,,tar時進(jìn)行追加。 find / -name "*.sh" | xargs -n 100 tar -rvf abc.tar This entry was posted in LINUX and tagged find, linux, xargs by admin. Bookmark the permalink. ONE THOUGHT ON “LINUX中XARGS的用法” xargs是給命令傳遞參數(shù)的一個過濾器,,也是組合多個命令的一個工具,。它把一個數(shù)據(jù)流分割為一些足夠小的塊,以方便過濾器和命令進(jìn)行處理,。通常情況下,,xargs從管道或者stdin中讀取數(shù)據(jù),但是它也能夠從文件的輸出中讀取數(shù)據(jù),。xargs的默認(rèn)命令是echo,,這意味著通過管道傳遞給xargs的輸入將會包含換行和空白,不過通過xargs的處理,,換行和空白將被空格取代,。 xargs 是一個強(qiáng)有力的命令,它能夠捕獲一個命令的輸出,,然后傳遞給另外一個命令,,下面是一些如何有效使用xargs 的實(shí)用例子。 1. 當(dāng)你嘗試用rm 刪除太多的文件,,你可能得到一個錯誤信息:/bin/rm Argument list too long. 用xargs 去避免這個問題 find ~ -name ‘*.log’ -print0 | xargs -0 rm -f 2. 獲得/etc/ 下所有*.conf 結(jié)尾的文件列表,,有幾種不同的方法能得到相同的結(jié)果,下面的例子僅僅是示范怎么實(shí)用xargs ,,在這個例子中實(shí)用 xargs將find 命令的輸出傳遞給ls -l # find /etc -name "*.conf" | xargs ls –l 3. 假如你有一個文件包含了很多你希望下載的URL, 你能夠使用xargs 下載所有鏈接 # cat url-list.txt | xargs wget –c 4. 查找所有的jpg 文件,,并且壓縮它 # find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz 5. 拷貝所有的圖片文件到一個外部的硬盤驅(qū)動 # ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory EXAMPLES find /tmp -name core -type f -print | xargs /bin/rm -f Find files named core in or below the directory /tmp and delete them. Note that this will work incorrectly if there are any filenames containing newlines or spaces. find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f Find files named core in or below the directory /tmp and delete them, processing filenames in such a way that file or directory names containing spaces or newlines are correctly handled. find /tmp -depth -name core -type f -delete Find files named core in or below the directory /tmp and delete them, but more efficiently than in the previous example (because we avoid the need to use fork(2) and exec(2) to launch rm and we don't need the extra xargs process). cut -d: -f1 < /etc/passwd | sort | xargs echo Generates a compact listing of all the users on the system. xargs sh -c 'emacs "$@" < /dev/tty' emacs Launches the minimum number of copies of Emacs needed, one after the other, to edit the files listed on xargs' standard input. This example achieves the same effect as BSD's -o option, but in a more flexible and portable way. |
|