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 |
當輸入不包括任何非空格時,不執行命令 |
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
-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
前面我們講過 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 命令的用法請查閱命令文檔
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!