xargs
- xargs
- 命令用法
[root@localhost xiangjis]# cat -E text1
11 apple$
12 pear$
13 banana$
[root@localhost xiangjis]# cat text1 | xargs \\此處為空格字符分隔
11 apple 12 pear 13 banana
空格分隔
為了方便看清楚,上圖匹配到的紅色部分,即為空格
[root@localhost xiangjis]# cat text1 | xargs -t \\默認的執行命令為echo,分隔符為空格,這里用到了-t選項,后邊還會有演示
echo 11 apple 12 pear 13 banana
11 apple 12 pear 13 banana
[root@localhost xiangjis]# echo aaa@bbb@ccc | xargs
aaa@bbb@ccc
[root@localhost xiangjis]# echo aaa@bbb@ccc | xargs -d @ \\指定分隔符為@
aaa bbb ccc
[root@localhost xiangjis]#
[root@localhost xiangjis]# xargs < text1 \\以上的參數都通過管道符傳遞的標準輸出,這個是來自標準輸入
11 apple 12 pear 13 banana
[root@localhost xiangjis]# xargs -a text1 \\指定參數來自文件
11 apple 12 pear 13 banana
[root@localhost xiangjis]# ls text* | cat \\管道符將ls運行的標準輸入當作標準輸入傳給cat運行
text1
text2
text3
[root@localhost xiangjis]# ls text* | xargs -p cat \\ls運行的標準輸出通過xargs運行后,被當作參數傳給cat運行
cat text1 text2 text3 ?...yes
11 apple
12 pear
13 banana
21 apple
22 pear
23 banana
31 apple
32 pear
33 banana
以上兩個標準輸出對比下,唯一的區別是是否通過xargs命令運行,通過xargs運行后,cat輸出的結果是文件的內容,而前者僅為文件的名字。前者cat 是將管道前命令的標準輸出作為標準輸入運行,后者cat將前者的標準輸出作為參數運行,而這都是xargs的功勞。
[root@localhost xiangjis]# ls text* | xargs -p cat
cat text1 text2 text3 ?...no
[root@localhost xiangjis]#
[root@localhost xiangjis]# ls text* | xargs -p cat
cat text1 text2 text3 ?...no
[root@localhost xiangjis]# ls text* | xargs -p -n 1 cat \\每次運行的參數數量為1個,默認按照空白字符分割每個命令參數
cat text1 ?...yes
11 apple
12 pear
13 banana
cat text2 ?...no
cat text3 ?...yes
31 apple
32 pear
33 banana
[root@localhost xiangjis]# ls text* | xargs -p -n 2 cat \\每次運行兩個參數,因為一共就三個參數,最后運行一個參數
cat text1 text2 ?...yes
11 apple
12 pear
13 banana
21 apple
22 pear
23 banana
cat text3 ?...yes
31 apple
32 pear
33 banana
[root@localhost xiangjis]# ls text* | xargs -p -E text2 cat \\只運行text2之前的參數
cat text1 ?...yes
11 apple
12 pear
13 banana
[root@localhost xiangjis]# ls text* | xargs -p -E text3 cat
cat text1 text2 ?...yes
11 apple
12 pear
13 banana
21 apple
22 pear
23 banana
[root@localhost xiangjis]# ls text* | xargs -t -E text2 cat
cat text1
11 apple
12 pear
13 banana
[root@localhost xiangjis]# ls text* | xargs -t -E text3 cat
cat text1 text2
11 apple
12 pear
13 banana
21 apple
22 pear
23 banana
[root@localhost xiangjis]# cat text1 | xargs
11 apple 12 pear 13 banana
[root@localhost xiangjis]# cat text1 | xargs -n1
11
apple
12
pear
13
banana
[root@localhost xiangjis]# cat text1 | xargs -n2 -t \\每次運行兩個參數
echo 11 apple
11 apple
echo 12 pear
12 pear
echo 13 banana
13 banana
[root@localhost xiangjis]# cat text1 | xargs -L2 -t \\將行當作參數,并設定一行兩個參數
echo 11 apple 12 pear
11 apple 12 pear
echo 13 banana
13 banana
[root@localhost xiangjis]# pwd
/tmp/mytest/xiangjis
[root@localhost xiangjis]# ls text*
text1 text2 text3
[root@localhost xiangjis]# ls text* | xargs -i -t cp {} .. \-i參數,指定默認替代符為{},該參數已漸漸被-I(大寫)取代
cp text1 ..
cp text2 ..
cp text3 ..
[root@localhost xiangjis]# ls ../text*
../text1 ../text2 ../text3
[root@localhost xiangjis]# ls ../text* | xargs -I [] -t rm [] \-I參數,指定[]為替換符
rm ../text1
rm ../text2
rm ../text3
[root@localhost xiangjis]# ls ../text*
ls: 無法訪問../text*: 沒有那個文件或目錄
[root@localhost xiangjis]# xargs -t -I x echo "(x)" < text1 \-I參數,指定x為替換符
echo (11 apple)
(11 apple)
echo (12 pear)
(12 pear)
echo (13 banana)
(13 banana)
[root@localhost xiangjis]# cp text1 'text 11' \\創建文件名包含空白字符的文件(此處為空格字符)
[root@localhost xiangjis]# ll text*
-rw-r--r--. 1 root root 27 9月 10 22:11 text1
-rw-r--r--. 1 root root 27 9月 12 07:57 text 11
-rw-r--r--. 1 root root 27 9月 10 22:11 text2
-rw-r--r--. 1 root root 27 9月 10 22:11 text3
[root@localhost xiangjis]# ls text* | xargs -t grep apple \\xargs默認的分割符為空白字符,所以文件text 11,被認為為兩個文件text和11,而這兩個文件是不存在的,所以報錯
grep apple text1 text 11 text2 text3
text1:11 apple
grep: text: 沒有那個文件或目錄
grep: 11: 沒有那個文件或目錄
text2:21 apple
text3:31 apple
[root@localhost xiangjis]# ls --quoting-style=escape text* \\通過此選項對文件名進行轉義
text1 text\ 11 text2 text3
[root@localhost xiangjis]# ls --quoting-style=shell text* \\通過此選項對文件名加上引號
text1 'text 11' text2 text3
[root@localhost xiangjis]# ls --quoting-style=shell text* | xargs -t grep apple \\解決方案一
grep apple text1 text 11 text2 text3
text1:11 apple
text 11:11 apple
text2:21 apple
text3:31 apple
[root@localhost xiangjis]# ls --quoting-style=escape text* | xargs -t grep apple
grep apple text1 text 11 text2 text3
text1:11 apple
text 11:11 apple
text2:21 apple
text3:31 apple
[root@localhost xiangjis]# ls text* | tr '\n' '\0' \\tr將文件名之間的換行符轉換成空字符
text1text 11text2text3
[root@localhost xiangjis]# ls text* | tr '\n' '\0' | xargs -0 -t grep apple \\解決方案二,此處運用了xargs -0選項
grep apple text1 text 11 text2 text3
text1:11 apple
text 11:11 apple
text2:21 apple
text3:31 apple
[root@localhost xiangjis]# find -name 'text*' -print0 \\find -print0,改變輸出的分割符為空字符
./text1./text2./text3./text 11
[root@localhost xiangjis]# find -name 'text*' -print0 | xargs -0 -t grep apple \\解決方案三,此處運用了xargs -0選項
grep apple ./text1 ./text2 ./text3 ./text 11
./text1:11 apple
./text2:21 apple
./text3:31 apple
./text 11:11 apple
[root@localhost xiangjis]# ls text* | xargs -t -I [] grep apple [] \\解決方案四(自創的),這里用到的主要是-I參數,因為其將行當作參數運行,而非空白字符為分隔符,指定[]為替換字符,指定grep運行其的位置也很關鍵,否則grep命令運行會報錯
grep apple text1
11 apple
grep apple text 11
11 apple
grep apple text2
21 apple
grep apple text3
31 apple
[root@localhost xiangjis]# find -name 'text*' -exec grep apple {} \; \\解決方案四,用find 的-exec,這個就不多說了,本次主要說用xargs的解決方案
11 apple
21 apple
31 apple
11 apple
- 總結
最后也可以用find的-exec參數來完成處理動作,但其支持的參數長度是有限的;所以find經常和xargs結合使用。
-
既然說到了find,在這里說下其-exec命令的用法,如下:
必須使用 {} 標記文件名在命令中的位置。它不是自動添加在末尾的
必須使用轉義后的分號終止該命令,比如 ;、';' 或 ";" 都行
該命令對每個輸入文件執行一次 -
本次演示很多地方只用到了管道符,有些地方到了管道符和xargs;大家也看到其運行的結果是截然不同的,下面就是兩者的主要區別:
管道是實現“將前面的標準輸出作為后面的標準輸入”
xargs是實現“將標準輸入作為命令的參數”