聊一聊Linux 下 Xargs 命令,你知道嗎?
xargs 常常被大家忽略的一個(gè)命令,對(duì)它的一些用法很多人可能不熟悉,其實(shí)它是一個(gè)功能強(qiáng)大的命令,特別是在結(jié)合管道進(jìn)行批量處理方面
語(yǔ)法
xargs 語(yǔ)法格式如下
- xargs [OPTION]... COMMAND
作用
xargs 最重要的作用是以空格或者換行作為分隔符,把標(biāo)準(zhǔn)輸入轉(zhuǎn)化成多個(gè)命令行參數(shù),在與管道命令結(jié)合使用時(shí),就能體現(xiàn)出 xargs 的作用
下面以實(shí)例來(lái)說(shuō)明
- [root@ecs-centos-7 tmp]# echo "11 22 33" | xargs mkdir
- [root@ecs-centos-7 tmp]# ll
- 總用量 16
- drwxr-xr-x 2 root root 4096 1月 20 00:03 11
- drwxr-xr-x 2 root root 4096 1月 20 00:03 22
- drwxr-xr-x 2 root root 4096 1月 20 00:03 33
上面的例子中, 管道左側(cè)的命令 echo "11 22 33" 的輸出作為管道右側(cè)命令 xargs mkdir 的輸入, 管道右側(cè)的命令將左側(cè)的輸入以空格或者換行為分隔符分成多個(gè)命令行的參數(shù)
所以 echo "11 22 33" | xargs mkdir 命令等同于下面的三條命令
- mkdir 11
- mkdir 22
- mkdir 33
選項(xiàng)說(shuō)明
選項(xiàng) | 說(shuō)明 |
---|---|
-d | 指定輸入?yún)?shù)的分隔符,默認(rèn)是以空格或換行作為分隔符 |
-p | 打印出將要執(zhí)行的命令,并詢問(wèn)用戶是否要執(zhí)行 |
-t | 打印出最終執(zhí)行的命令并執(zhí)行,不需要用戶確認(rèn) |
-0 | 表示用 null 作為分隔符 |
-n | 每次將一行中的多少項(xiàng)參數(shù)作為命令行參數(shù) |
-I | 指定每一項(xiàng)命令行參數(shù)的替代字符串,類(lèi)似一個(gè)存儲(chǔ)參數(shù)項(xiàng)的中間變量 |
-r | 當(dāng)輸入不包括任何非空格時(shí),不執(zhí)行命令 |
實(shí)例1 不帶任何選項(xiàng)的 xargs
xargs 命令大部分是和管道一起使用,但是它也可以單獨(dú)使用, 這時(shí)候xargs相當(dāng)于 echo 命令,把用戶的輸入通過(guò)echo命令輸出到屏幕
- [root@ecs-centos-7 ~]# xargs
- hello
- world
- ! ( ctrl + d )
- hello world !
- [root@ecs-centos-7 ~]#
上面的例子中,輸入xargs 并回車(chē)之后,開(kāi)始接受用戶輸入,用戶輸入 hello world !后,按 ctrl + d 結(jié)束輸入,結(jié)束之后,屏幕上會(huì)輸出用戶輸入的內(nèi)容
實(shí)例2 -d 選項(xiàng)
-d選項(xiàng)可以指定 xargs 命令的分隔符
- [root@ecs-centos-7 ~]# echo -n "a#b#c" | xargs echo
- a#b#c
- [root@ecs-centos-7 ~]# echo -n "a#b#c" | xargs -d "#" echo
- a b c
上面實(shí)例中,指定分隔符為 # ,所以 "a#b#c" 就被轉(zhuǎn)換成了 a b c 三個(gè)命令行參數(shù)了
實(shí)例3 -p 選項(xiàng)
-p選項(xiàng)會(huì)打印出將要執(zhí)行的命令,并且執(zhí)行命令前做依次是否執(zhí)行的二次確認(rèn),y 表示確認(rèn)執(zhí)行,n 表示取消執(zhí)行
- [root@ecs-centos-7 tmp]# echo "a b c" | xargs -p touch
- touch a b c ?...y
- [root@ecs-centos-7 tmp]# ll
- 總用量 0
- -rw-r--r-- 1 root root 0 1月 20 00:46 a
- -rw-r--r-- 1 root root 0 1月 20 00:46 b
- -rw-r--r-- 1 root root 0 1月 20 00:46 c
實(shí)例4 -t 選項(xiàng)
-t 選項(xiàng)打印出最終執(zhí)行的命令,并且直接執(zhí)行命令,不再需要用戶二次確認(rèn)
- [root@ecs-centos-7 tmp]# ll
- 總用量 0
- -rw-r--r-- 1 root root 0 1月 20 00:49 a
- -rw-r--r-- 1 root root 0 1月 20 00:49 b
- -rw-r--r-- 1 root root 0 1月 20 00:49 c
- [root@ecs-centos-7 tmp]# echo "a b c" | xargs -t rm
- rm a b c
實(shí)例5 -0 選項(xiàng)
前面我們講過(guò) xargs 命令是以空格或換行為分隔符的,大部分情況下執(zhí)行都是正常的,但是有一種情況下會(huì)出現(xiàn)問(wèn)題,那就是當(dāng)文件名中包含空格的時(shí)候
含有空格的文件名當(dāng)作輸入傳給 xargs 的時(shí)候,會(huì)被 xargs 當(dāng)作多個(gè)命令行參數(shù)來(lái)處理
下面的例子重現(xiàn)了問(wèn)題
- [tt@ecs-centos-7 tmp]$ ls
- a.txt b 1.txt c.txt
- [tt@ecs-centos-7 tmp]$ ls | xargs -t rm
- rm a.txt b 1.txt c.txt
- rm: 無(wú)法刪除"b": 沒(méi)有那個(gè)文件或目錄
- rm: 無(wú)法刪除"1.txt": 沒(méi)有那個(gè)文件或目錄
- [tt@ecs-centos-7 tmp]$
例子中,通過(guò) ls 命令知道目錄下有 a.txt b 1.txt c.txt 三個(gè)文件
當(dāng)通過(guò) ls | xargs -t rm 命令來(lái)刪除目錄下所有文件的時(shí)候發(fā)現(xiàn),a.txt 和 c.txt 都能被正確的刪除,但是 b 1.txt文件名中包含空格,刪除的時(shí)候會(huì)被當(dāng)作 b 和 1.txt 兩個(gè)文件處理
所以,例子中輸出結(jié)果中才會(huì)出現(xiàn) rm: 無(wú)法刪除"b": 沒(méi)有那個(gè)文件或目錄 和 rm: 無(wú)法刪除"1.txt": 沒(méi)有那個(gè)文件或目錄 的錯(cuò)誤提示
上述的問(wèn)題可以通過(guò) -0 選項(xiàng)結(jié)合find 命令來(lái)解決
- [tt@ecs-centos-7 tmp]$ ls
- a.txt b 1.txt c.txt
- [tt@ecs-centos-7 tmp]$ find . -type f -print0 | xargs -0 -t rm
- rm ./a.txt ./b 1.txt ./c.txt
- [tt@ecs-centos-7 tmp]$ ll
- 總用量 0
- [tt@ecs-centos-7 tmp]$
find 命令的 -print0 選項(xiàng)表示輸出的文件列表以 null 分隔
同時(shí),xargs 命令的 -0 選項(xiàng)表示以 null 作為分隔符
從輸出結(jié)果可以看出,-0選項(xiàng)結(jié)合find命令可以正確的刪除包含空格的文件名
實(shí)例6 -n 選項(xiàng)
有時(shí)用戶會(huì)輸入多個(gè)參數(shù),-n 選項(xiàng)是每次將一行中的多少個(gè)參數(shù)作為命令行參數(shù)
- [tt@ecs-centos-7 tmp]$ echo "a b c d e f" | xargs -n 2
- a b
- c d
- e f
- [tt@ecs-centos-7 tmp]$ echo "a b c d e f" | xargs -n 4
- a b c d
- e f
- [tt@ecs-centos-7 tmp]$
命令 echo "a b c d e f" | xargs -n 2 指定每2個(gè)參數(shù)作為一次命令的輸出,所以 a b c d e f 6個(gè)參數(shù)輸出了3行
同樣的,命令 echo "a b c d e f" | xargs -n 4 指定每4個(gè)參數(shù)作為一次輸出,所以 a b c d e f 6個(gè)參數(shù)輸出2行,而且第2行只有兩個(gè)參數(shù)
實(shí)例7 -r 選項(xiàng)
此選項(xiàng)表示,當(dāng)輸入不包含非空格時(shí),不執(zhí)行命令,默認(rèn)情況下,不管輸入是否包含非空格時(shí),都會(huì)執(zhí)行命令
有些命令必須要有操作數(shù),如果輸入不包含任何參數(shù)時(shí),執(zhí)行這些命令會(huì)有缺少操作數(shù)的錯(cuò)誤提示,可以加上 -r選項(xiàng)就不會(huì)出現(xiàn)錯(cuò)誤提示了
- [tt@ecs-centos-7 tmp]$ echo '' | xargs rm
- rm: 缺少操作數(shù)
- Try 'rm --help' for more information.
- [tt@ecs-centos-7 tmp]$ echo '' | xargs -r rm
- [tt@ecs-centos-7 tmp]$
上面的例子中,命令 echo ''的結(jié)果作為輸入傳給管道右邊的 xargs rm ,經(jīng)過(guò)參數(shù)轉(zhuǎn)化,xargs rm 沒(méi)有任何參數(shù),所以執(zhí)行 rm 命令時(shí)會(huì)提示缺少操作數(shù),但是 xargs -r rm 命令是不會(huì)執(zhí)行的,所以它不會(huì)有錯(cuò)誤提示
實(shí)例8 -I 參數(shù)
-I 參數(shù)表示命令行參數(shù)的每一項(xiàng)參數(shù)的變量
- [tt@ecs-centos-7 tmp]$ ls
- a b c
- [tt@ecs-centos-7 tmp]$ ls | sort | xargs -I F sh -c 'echo F.txt; touch F.txt'
- a.txt
- b.txt
- c.txt
- [tt@ecs-centos-7 tmp]$ ls
- a a.txt b b.txt c c.txt
上面例子中,當(dāng)前目錄有 a b c 三個(gè)文件
命令 ls | sort | xargs -I F sh -c 'echo F.txt; touch F.txt' 的輸入分別是 a、b、c, -I F表示 F 是輸入?yún)?shù)的替代字符串,執(zhí)行命令的時(shí)候,后面命令 echo F.txt; touch F.txt 中的 F 會(huì)被實(shí)際的參數(shù)替換掉,實(shí)際會(huì)執(zhí)行下面幾條命令
- echo a.txt; touch a.txt
- echo b.txt; touch b.txt
- echo c.txt; touch c.txt
小結(jié)
本文介紹了 xargs 命令的常見(jiàn)用法,常用的選項(xiàng)都有實(shí)例說(shuō)明,更多關(guān)于 xargs 命令的用法請(qǐng)查閱命令文檔