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