一天一個 Linux 命令(22):xargs 命令
本文為joshua317原創文章,轉載請註明:轉載自joshua317部落格https://www.joshua317.com/article/156
一、簡介
xargs英文全拼: extended arguments
xargs 是給命令傳遞引數的一個過濾器,也是組合多個命令的一個工具。
xargs 可以將管道或標準輸入(stdin)資料轉換成命令列引數,也能夠從檔案的輸出中讀取資料。
xargs 也可以將單行或多行文字輸入轉換為其他格式,例如多行變單行,單行變多行。
xargs 預設的命令是 echo,這意味著通過管道傳遞給 xargs 的輸入將會包含換行和空白,不過通過 xargs 的處理,換行和空白將被空格取代。
xargs 是一個強有力的命令,它能夠捕獲一個命令的輸出,然後傳遞給另外一個命令。
簡單來說,xargs 的作用是給其他命令傳遞引數,是構建單行命令的重要元件之一。
之所以會有這個命令,主要是因為很多命令不支援|
管道來傳遞引數,而日常工作中卻有這個必要,所以就有了 xargs 命令。
二、格式說明
xargs [OPTION]... COMMAND INITIAL-ARGS... Mandatory arguments to long options are mandatory for short options too. Non-mandatory arguments are indicated by [square brackets] -0, --null Items are separated by a null, not whitespace. Disables quote and backslash processing -a, --arg-file=FILE Read arguments from FILE, not standard input -d, --delimiter=CHARACTER Input items are separated by CHARACTER, not by blank space. Disables quote and backslash processing -E END If END occurs as a line of input, the rest of the input is ignored. -e [END], --eof[=END] Equivalent to -E END if END is specified. Otherwise, there is no end-of-file string --help Print a summary of the options to xargs. -I R same as --replace=R (R must be specified) -i,--replace=[R] Replace R in initial arguments with names read from standard input. If R is unspecified, assume {} -L,-l, --max-lines=MAX-LINES Use at most MAX-LINES nonblank input lines per command line -l Use at most one nonblank input line per command line -n, --max-args=MAX-ARGS Use at most MAX-ARGS arguments per command line -P, --max-procs=MAX-PROCS Run up to max-procs processes at a time -p, --interactive Prompt before running commands --process-slot-var=VAR Set environment variable VAR in child processes -r, --no-run-if-empty If there are no arguments, run no command. If this option is not given, COMMAND will be run at least once. -s, --max-chars=MAX-CHARS Limit commands to MAX-CHARS at most --show-limits Show limits on command-line length. -t, --verbose Print commands before executing them --version Print the version number -x, --exit Exit if the size (see -s) is exceeded
注意,xargs一般不會單獨使用, 一般都是是和管道符|
一起使用的。
command |xargs -item command
三、選項說明
-0, --null 如果輸入的 stdin 含有特殊字元,例如反引號 `、反斜槓 \、空格等字元時,xargs 將它還原成一般字元。為預設選項 -a, --arg-file=FILE 從指定的檔案 FILE 中讀取輸入內容而不是從標準輸入 -d, --delimiter=DEL 指定 xargs 處理輸入內容時的分隔符。xargs 處理輸入內容預設是按空格和換行符作為分隔符,輸出 arguments 時按空格分隔 -E EOF_STR EOF_STR 是 end of file string,表示輸入的結束 -e, --eof[=EOF_STR] 作用等同於 -E 選項,與 -E 選項不同時,該選項不符合 POSIX 標準且 EOF_STR 不是強制的。如果沒有 EOF_STR 則表示輸入沒有結束符 -I REPLACE_STR 將 xargs 輸出的每一項引數單獨賦值給後面的命令,引數需要用指定的替代字串 REPLACE_STR 代替。REPLACE_STR 可以使用 {} $ @ 等符號,其主要作用是當 xargs command 後有多個引數時,調整引數位置。例如備份以 txt 為字尾的檔案:find . -name "*.txt" | xargs -I {} cp {} /tmp/{}.bak -i, --replace[=REPLACE_STR] 作用同 -I 選項,引數 REPLACE_STR 是可選的,預設為 {}。建議使用 -I 選項,因為其符合 POSIX -L MAX_LINES 限定最大輸入行數。隱含了 -x 選項 -l, --max-lines[=MAX_LINES] 作用同 -L 選項,引數 MAX_LINES 是可選的,預設為 1。建議使用 -L 選項,因為其符合 POSIX 標準 -n, --max-args=MAX_ARGS 表示命令在執行的時候一次使用引數的最大個數 -o, --open-tty 在執行命令之前,在子程序中重新開啟stdin作為/dev/TTY。如果您希望xargs執行互動式應用程式,這是非常有用的 -P, --max-procs=MAX_PROCS 每次執行最大程序;預設值為 1。如果 MAX_PROCS 為 0,xargs 將一次執行儘可能多的程序。一般和 -n 或 -L 選項一起使用 -p, --interactive 當每次執行一個 argument 的時候詢問一次使用者 --process-slot-var=NAME 將指定的環境變數設定為每個正在執行的子程序中的唯一值。一旦子程序退出,將重用該值。例如,這可以用於初始負荷分配方案 -r, --no-run-if-empty 當 xargs 的輸入為空的時候則停止 xargs,不用再去執行後面的命令了。為預設選項 -s, --max-chars=MAX_CHARS 命令列的最大字元數,指的是 xargs 後面那個命令的最大命令列字元數,包括命令、空格和換行符。每個引數單獨傳入 xargs 後面的命令 --show-limits 顯示作業系統對命令列長度的限制 -t, --verbose 先列印命令到標準錯誤輸出,然後再執行 --help 顯示幫助資訊並退出 --version 顯示版本資訊並退出 -x, --exit 配合 -s 使用,當命令列字元數大於 -s 指定的數值時,退出 xargs
注意,長選項的強制性引數對於短選項也是強制的。
四、命令功能
結合其他命令,將標準輸入轉為命令列引數
五、常見用法
1.將管道左側的標準輸入,轉為命令列引數hello world
,傳給第二個echo
命令
# echo "hello world"|xargs echo
hello world
2.將shell 的特殊字元反引號還原為一般字元
# echo '`hello` world'|xargs echo
`hello` world
如果直接執行以下操作,會報無法找到命令 hello的錯誤,因為反引號在shell中會將hello作為一個命令來執行,但是 hello不是一個命令
# echo `hello` world
-bash: hello: command not found
world
如果使用-t引數,則表示先列印命令,然後再執行
# echo '`hello` world'|xargs -t echo
echo `hello` world
`hello` world
3.從指定的檔案中讀取輸入內容,然後重新格式化後輸出
首先,先定義一個測試檔案test.txt
# cat test.txt
hello
i
love
China
,
my
name
is
joshua317
多行輸入單行輸出
# cat test.txt |xargs
hello i love China , my name is joshua317
-n 選項多行輸出
# cat test.txt |xargs -n5
hello i love China ,
my name is joshua317
-d 選項可以自定義一個分隔符
# cat test.txt |xargs -d","
hello
i
love
China
my
name
is
joshua317
預設情況下,xargs
將換行符和空格作為分隔符,把標準輸入分解成一個個命令列引數。
4.從指定的檔案中讀取輸入內容而不是從標準輸入,然後執行命令
首先,先定義一個檔案ip.txt
# cat ip.txt
www.baidu.com
114.114.114.114
www.qq.com
xargs
命令使用-a
選項,後跟檔名,從檔案讀取內容,使用-L 1
選項,該選項表示xargs一次讀取一行。如果省略此選項,xargs將把所有ip傳遞給一個ping命令。
# xargs -a ip.txt -t -L 1 ping -c 1
ping -c 1 www.baidu.com
PING www.a.shifen.com (110.242.68.3) 56(84) bytes of data.
64 bytes from 110.242.68.3 (110.242.68.3): icmp_seq=1 ttl=251 time=10.6 ms
--- www.a.shifen.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 10.636/10.636/10.636/0.000 ms
ping -c 1 114.114.114.114
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
64 bytes from 114.114.114.114: icmp_seq=1 ttl=251 time=33.3 ms
--- 114.114.114.114 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 33.327/33.327/33.327/0.000 ms
ping -c 1 www.qq.com
PING ins-r23tsuuf.ias.tencent-cloud.net (175.27.8.138) 56(84) bytes of data.
64 bytes from 175.27.8.138 (175.27.8.138): icmp_seq=1 ttl=56 time=4.42 ms
--- ins-r23tsuuf.ias.tencent-cloud.net ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 4.426/4.426/4.426/0.000 ms
與wget 結合,下載檔案內的所有連結
假設有一個檔案包含了很多你希望下載的 URL,你能夠使用 xargs下載所有連結
# cat url-list.txt | xargs wget -c
5.使用管道符|
傳輸到xargs,併為每個引數執行touch命令
# echo "file1 file2 file3"|xargs -t touch
touch file1 file2 file3
如果執行前需要詢問是否執行,則使用-p引數
# echo "file1 file2 file3"|xargs -t -p touch
touch file1 file2 file3 ?...
如果需要xargs多次執行指定的命令,則使用-n
引數,指定要傳遞給命令的引數個數,認情況下,傳遞給命令的引數數量由系統限制決定。
# echo "file1 file2 file3"|xargs -t -p -n1 touch
touch file1 ?...y
touch file2 ?...y
touch file3 ?...y
6.如何在xargs後面執行多項命令
要使用xargs執行多個命令,使用-i
或者-I
選項。在-i
或者-I
後面自定義一個傳遞引數符號,如%
,所有匹配的項都會替換為傳遞給xargs的引數。
# echo "file1 file2 file3"|xargs -t -I % sh -c 'touch %;ls -l %'
sh -c touch file1 file2 file3;ls -l file1 file2 file3
-rw-r--r-- 1 root root 0 Oct 8 10:53 file1
-rw-r--r-- 1 root root 0 Oct 8 10:53 file2
-rw-r--r-- 1 root root 0 Oct 8 10:53 file3
刪除上面建立的檔案
# echo "file1 file2 file3"|xargs -t -I % sh -c 'ls -l %;rm %'
sh -c ls -l file1 file2 file3;rm file1 file2 file3
-rw-r--r-- 1 root root 0 Oct 8 10:53 file1
-rw-r--r-- 1 root root 0 Oct 8 10:53 file2
-rw-r--r-- 1 root root 0 Oct 8 10:53 file3
複製當前目錄下的所有log檔案到 /data/logs目錄下
xargs 的一個選項-I
,使用-I
指定一個替換字串%
,這個字串在 xargs 擴充套件時會被替換掉,當-I
與 xargs 結合使用,每一個引數命令都會被執行一次
ls *.log | xargs -n1 -I % cp % /data/logs
7.xargs與find一起使用
用 rm 刪除太多的檔案時候,可能得到一個錯誤資訊:/bin/rm Argument list too long.,"引數列表過長",而無法執行,用 xargs 去避免這個問題
find /data/log -type f -name "*.log" -print0 | xargs -0 rm -f
查詢所有的 log 檔案,並且壓縮它們:
find . -type f -name "*.log" -print0 | xargs -0 tar -czvf log.tar.gz
注意:
由於xargs
預設將空格作為分隔符,所以不太適合處理檔名,因為檔名可能包含空格。
find
命令有一個特別的引數-print0
,指定輸出的檔案列表以null
分隔。然後,xargs
命令的-0
引數表示用null
當作分隔符。所以要避免包含換行符或其他特殊字元的檔名出現問題,請始終使用find的-print0選項,這樣可以使find列印完整的檔名,配合xargs命令使用-0或者--null選項可以正確的執行。
查詢檔案裡面包含的字元
找出當前目錄下所有 log檔案以後,對每個檔案搜尋一次是否包含字串joshua317
。
# find . -name "*.log" | xargs grep "joshua317"
從根目錄開始查詢所有副檔名為.log的文字檔案,並找出包含"ERROR"的行
find / -type f -name "*.log" | xargs grep "ERROR"
8.批量殺掉多個php程序
ps -ef|grep php|grep -v grep|cut -c 9-15|xargs kill -9
持續整理。。。
本文為joshua317原創文章,轉載請註明:轉載自joshua317部落格https://www.joshua317.com/article/156