xargs原來意思是build and execute command lines frooom standarad input(stdin)
xargs把從stdin接受到的字串, 轉成後面命令的參數, 來執行後面的命令.
為什麼講這個命令呢?
之前介紹grep、sed、awk,
grep找到的內容可以給sed、awk直接讀取
但若我是取出檔名, 要給後兩者讀取其內容呢?
這時xargs可以幫忙處理
# 搜尋txt檔案內容有it的, 顯示其檔名
grep -l 'it' *.txt
> aa.txt
> python.txt
# 透過xargs將檔名當成sed的參數, 來執行sed
grep -l 'it' *.txt | xargs sed -n 's/it/ithome/p'
> baseurl=https://xxx/mysql-repo/yum/mysql-5.7-communithomey/el/$releasever/$basearch
> 13Th Ithome is my favorithomee active
轉個思維表示;
系統內的日誌也是能grep找出來含內容的檔案, 再轉給awk做格式轉換製作表格後,
再輸出到類似kibana等等的地方做儲存展示.
也能是用grep轉到執行自己寫的程式, 將檔名當成參數.
xargs預設是用空格
做完分隔符號, 也就是說,
echo "aa.txt python.txt" | xargs sed -n 's/it/ithome/p'
> baseurl=https://xxx/mysql-repo/yum/mysql-5.7-communithomey/el/$releasever/$basearch
> 13Th Ithome is my favorithomee active
xargs會將"aa.txt python.txt"按照空格切成aa.txt、python.txt,
傳給sed當參數sed -n 's/it/ithome/p' aa.txt python.txt
, 然後執行.
也能指定分隔符號, 透過-d
delimiter,
# 指定@為分隔符號
echo '11@22@33' | xargs -d '@' echo
> 11 22 33
也能指定EOF符號-E
, 表示讀到EOF就不會再讀取字串, 也不會去執行命令
ps 但無法跟上一個-d
一起混用
# 指定22為EOF, 因此33就不被讀取, 22是不被拿去echo給執行去
echo '11 22 33' | xargs -E '22' echo
> 11
透過-t
verbose, 能把要執行的命令給輸出出來, 並且執行該命令
# 能看到真正要執行的命令
grep -l 'it' *.txt | xargs -t sed -n 's/it/ithome/p'
> sed -n s/it/ithome/p aa.txt python.txt
> baseurl=https://xxx/mysql-repo/yum/mysql-5.7-communithomey/el/$releasever/$basearch
> 13Th Ithome is my favorithomee active
透過-p
interactive, 這命令就只是一個prompt, 詢問是否要執行, 輸入y/Y, 就真正執行該命令
通常會跟上一個-t
搭配使用
grep -l 'it' *.txt | xargs -tp sed -n 's/it/ithome/p'
# 會顯示命令並且等待用戶輸入, 這裡我輸入y
> sed -n s/it/ithome/p aa.txt python.txt ?...y
> baseurl=https://xxx/mysql-repo/yum/mysql-5.7-communithomey/el/$releasever/$basearch
> 13Th Ithome is my favorithomee active
玩一下之前學到的,做組合拳
先開一個新的terminal, 掛著讓它跑
ping -i 1 8.8.8.8
再開另一個terminal
然後透過ps找到這執行中的PID, 透過xargs傳給kill執行
ps -ef | grep 'ping -i' | awk '{print $2}' | xargs -t kill -9
> kill -9 242585 242668
> kill: (242241): No such process
執行完, 原本持續在ping的process就會收到kill訊號而被kill.
這裡用到之前的grep+awk
掌握這些基本也能, 做到說像是去redis找到key, 然後再去刪除key
./redis-cli -h 127.0.0.1 -p 6381 -n 1 KEYS "ithome:*" | xargs ./redis-cli -h 127.0.0.1 -p 6381 -n 1 DEL
很多組合的操作, 其實大多都能通過xargs中間轉一手來處理.
因為不是每個工具都支持pipeline的使用,
有xargs就能讓這些不支持的程式, 可以使用前一個命令完成之後的結果.
真的是個很方便的工具
----參考來源
鳥哥Linux私房菜 xargs