一天一個 Linux 命令(22):xargs 命令


一、簡介

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

持續整理。。。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM