慣性聚合 高效追蹤和閱讀你感興趣的部落格、新聞、科技資訊
閱讀原文 在慣性聚合中打開

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

阮一峰的网络日志

科技爱好者周刊(第 396 期):互联网通信的替代方案 科技爱好者周刊(第 396 期):互联网通信的替代方案 - 阮一峰的网络日志 科技爱好者周刊(第 395 期):软件开发的第三种方式 科技爱好者周刊(第 395 期):软件开发的第三种方式 - 阮一峰的网络日志 科技爱好者周刊(第 393 期):脑腐状态 科技爱好者周刊(第 392 期):axios 投毒与好莱坞式骗术 科技爱好者周刊(第 391 期):AI 的贫富分化 科技爱好者周刊(第 390 期):没有语料,大模型就是智障 套壳中国大模型撑起500亿美元估值?扒一扒 Cursor 的"套壳"疑云 科技爱好者周刊(第 389 期):未来如何招聘程序员 科技爱好者周刊(第 388 期):测试是新的护城河 零安装的"云养虾":ArkClaw 使用指南 科技爱好者周刊(第 387 期):你是领先的 科技爱好者周刊(第 386 期):当外卖员接入 AI 字节全家桶 Seed 2.0 + TRAE 玩转 Skill 科技爱好者周刊(第 385 期):马斯克害怕中国车企吗? 智谱旗舰 GLM-5 实测:对比 Opus 4.6 和 GPT-5.3-Codex 科技爱好者周刊(第 384 期):为什么软件股下跌 科技爱好者周刊(第 383 期):你是第几级 AI 编程 Kimi 的一体化,Manus 的分层 科技爱好者周刊(第 382 期):独立软件的黄昏 AI native Workspace 也许是智能体的下一阶段 科技爱好者周刊(第 381 期):中国 AI 大模型领导者在想什么 科技爱好者周刊(第 380 期):为什么人们拥抱"不对称收益" 科技爱好者周刊(第 379 期):《硅谷钢铁侠》摘录 我如何用 AI 处理历史遗留代码:MiniMax M2.1 升级体验 科技爱好者周刊(第 378 期):预测是新的互联网热点 科技爱好者周刊(第 377 期):14万美元的贫困线 科技爱好者周刊(第 376 期):太空数据中心的争议 科技爱好者周刊(第 375 期):一扇门的 Bug 终于有人做了 Subagent,TRAE 国内版 SOLO 模式来了 科技爱好者周刊(第 374 期):6GHz 的问题 VS Code 使用国产大模型 MiniMax M2 教程 科技爱好者周刊(第 373 期):数据模型是新产品的核心 国产大模型接入 Claude Code 教程:以 Doubao-Seed-Code 为例 科技爱好者周刊(第 372 期):软件界面如何设计 大模型比拼:MiniMax M2 vs GLM 4.6 vs Claude Sonnet 4.5 科技爱好者周刊(第 371 期):一个乐观主义者的专访 科技爱好者周刊(第 370 期):正确的代码高亮 错误处理:异常好于状态码 科技爱好者周刊(第 369 期):Tim 与罗永浩的对谈 科技爱好者周刊(第 368 期):不要这样管理软件团队 一天之内,智谱和 Anthropic 都发了最强编程模型 科技爱好者周刊(第 367 期):Nano Banana 的几个妙用 科技爱好者周刊(第 366 期):旧金山疯狂的 AI 广告 科技爱好者周刊(第 365 期):流量变现正在崩塌 科技爱好者周刊(第 364 期):最难还原的魔方 科技爱好者周刊(第 363 期):最好懂的神经网络解释 科技爱好者周刊(第 362 期):GitHub 工程师谈系统设计 科技爱好者周刊(第 361 期):暗网 Tor 安全吗?
xargs 命令教程
阮一峰 · 2019-08-08 · via 阮一峰的网络日志

xargs是 Unix 系統的一個很有用的命令,但是常常被忽視,很多人不瞭解它的用法。

本文介紹如何使用這個命令。

一、標準輸入與管道命令

Unix 命令都帶有參數,有些命令可以接受"標準輸入"(stdin)作為參數。


$ cat /etc/passwd | grep root

上面的代碼使用了管道命令(|)。管道命令的作用,是將左側命令(cat /etc/passwd)的標準輸出轉換為標準輸入,提供給右側命令(grep root)作為參數。

因為grep命令可以接受標準輸入作為參數,所以上面的代碼等同於下面的代碼。


$ grep root /etc/passwd

但是,大多數命令都不接受標準輸入作為參數,只能直接在命令行輸入參數,這導致無法用管道命令傳遞參數。舉例來說,echo命令就不接受管道傳參。


$ echo "hello world" | echo

上面的代碼不會有輸出。因為管道右側的echo不接受管道傳來的標準輸入作為參數。

二、xargs 命令的作用

xargs命令的作用,是將標準輸入轉為命令行參數。


$ echo "hello world" | xargs echo
hello world

上面的代碼將管道左側的標準輸入,轉為命令行參數hello world,傳給第二個echo命令。

xargs命令的格式如下。


$ xargs [-options] [command]

真正執行的命令,緊跟在xargs後面,接受xargs傳來的參數。

xargs的作用在於,大多數命令(比如rmmkdirls)與管道一起使用時,都需要xargs將標準輸入轉為命令行參數。


$ echo "one two three" | xargs mkdir

上面的代碼等同於mkdir one two three。如果不加xargs就會報錯,提示mkdir缺少操作參數。

三、xargs 的單獨使用

xargs後面的命令默認是echo


$ xargs
# 等同於
$ xargs echo

大多數時候,xargs命令都是跟管道一起使用的。但是,它也可以單獨使用。

輸入xargs按下回車以後,命令行就會等待用戶輸入,作為標準輸入。你可以輸入任意內容,然後按下Ctrl d,表示輸入結束,這時echo命令就會把前面的輸入打印出來。


$ xargs
hello (Ctrl + d)
hello

再看一個例子。


$ xargs find -name
"*.txt"
./foo.txt
./hello.txt

上面的例子輸入xargs find -name以後,命令行會等待用戶輸入所要搜索的文件。用戶輸入"*.txt",表示搜索當前目錄下的所有 TXT 文件,然後按下Ctrl d,表示輸入結束。這時就相當執行find -name *.txt

四、-d 參數與分隔符

默認情況下,xargs將換行符和空格作為分隔符,把標準輸入分解成一個個命令行參數。


$ echo "one two three" | xargs mkdir

上面代碼中,mkdir會新建三個子目錄,因為xargsone two three分解成三個命令行參數,執行mkdir one two three

-d參數可以更改分隔符。


$ echo -e "a\tb\tc" | xargs -d "\t" echo
a b c

上面的命令指定製表符\t作為分隔符,所以a\tb\tc就轉換成了三個命令行參數。echo命令的-e參數表示解釋轉義字符。

五、-p 參數,-t 參數

使用xargs命令以後,由於存在轉換參數過程,有時需要確認一下到底執行的是什麼命令。

-p參數打印出要執行的命令,詢問用戶是否要執行。


$ echo 'one two three' | xargs -p touch
touch one two three ?...

上面的命令執行以後,會打印出最終要執行的命令,讓用戶確認。用戶輸入y以後(大小寫皆可),才會真正執行。

-t參數則是打印出最終要執行的命令,然後直接執行,不需要用戶確認。


$ echo 'one two three' | xargs -t rm
rm one two three

六、-0 參數與 find 命令

由於xargs默認將空格作為分隔符,所以不太適合處理文件名,因為文件名可能包含空格。

find命令有一個特別的參數-print0,指定輸出的文件列表以null分隔。然後,xargs命令的-0參數表示用null當作分隔符。


$ find /path -type f -print0 | xargs -0 rm

上面命令刪除/path路徑下的所有文件。由於分隔符是null,所以處理包含空格的文件名,也不會報錯。

還有一個原因,使得xargs特別適合find命令。有些命令(比如rm)一旦參數過多會報錯"參數列表過長",而無法執行,改用xargs就沒有這個問題,因為它對每個參數執行一次命令。


$ find . -name "*.txt" | xargs grep "abc"

上面命令找出所有 TXT 文件以後,對每個文件搜索一次是否包含字符串abc

七、-L 參數

如果標準輸入包含多行,-L參數指定多少行作為一個命令行參數。


$ xargs find -name
"*.txt"   
"*.md"
find: paths must precede expression: `*.md'

上面命令同時將"*.txt"*.md兩行作為命令行參數,傳給find命令導致報錯。

使用-L參數,指定每行作為一個命令行參數,就不會報錯。


$ xargs -L 1 find -name
"*.txt"
./foo.txt
./hello.txt
"*.md"
./README.md

上面命令指定了每一行(-L 1)作為命令行參數,分別運行一次命令(find -name)。

下面是另一個例子。


$ echo -e "a\nb\nc" | xargs -L 1 echo
a
b
c

上面代碼指定每行運行一次echo命令,所以echo命令執行了三次,輸出了三行。

八、-n 參數

-L參數雖然解決了多行的問題,但是有時用戶會在同一行輸入多項。


$ xargs find -name
"*.txt" "*.md"
find: paths must precede expression: `*.md'

上面的命令將同一行的兩項作為命令行參數,導致報錯。

-n參數指定每次將多少項,作為命令行參數。


$ xargs -n 1 find -name

上面命令指定將每一項(-n 1)標準輸入作為命令行參數,分別執行一次命令(find -name)。

下面是另一個例子。


$ echo {0..9} | xargs -n 2 echo
0 1
2 3
4 5
6 7
8 9

上面命令指定,每兩個參數運行一次echo命令。所以,10個阿拉伯數字運行了五次echo命令,輸出了五行。

九、-I 參數

如果xargs要將命令行參數傳給多個命令,可以使用-I參數。

-I指定每一項命令行參數的替代字符串。


$ cat foo.txt
one
two
three

$ cat foo.txt | xargs -I file sh -c 'echo file; mkdir file'
one 
two
three

$ ls 
one two three

上面代碼中,foo.txt是一個三行的文本文件。我們希望對每一項命令行參數,執行兩個命令(echomkdir),使用-I file表示file是命令行參數的替代字符串。執行命令時,具體的參數會替代掉echo file; mkdir file裡面的兩個file

十、--max-procs 參數

xargs默認只用一個進程執行命令。如果命令要執行多次,必須等上一次執行完,才能執行下一次。

--max-procs參數指定同時用多少個進程並行執行命令。--max-procs 2表示同時最多使用兩個進程,--max-procs 0表示不限制進程數。


$ docker ps -q | xargs -n 1 --max-procs 0 docker kill

上面命令表示,同時關閉儘可能多的 Docker 容器,這樣運行速度會快很多。

十一、參考鏈接

(完)