xargs 命令详解
更新时间:2026-08-28。本文是「一个命令一个文档」系列,聚焦
xargs——管道里的"粘合剂"(见文本处理命令族)。它常和 find、grep 搭档。
很多命令不接受管道输入,只认"命令行参数"。比如 rm 不能 find ... | rm,因为 rm 要的是参数不是 stdin。**xargs** 干的事就是:把前面管道送来的文本,变成后面命令的参数。
一、最基本的用法
find . -name "*.tmp" | xargs rm # 把找到的文件名当成 rm 的参数
ls *.txt | xargs wc -l # 统计多个 txt 的行数
cat urls.txt | xargs curl -O # 批量下载默认
xargs以空白(空格/制表/换行)切分输入,多个词会拼成一条命令的多个参数。一行输入如果有多个文件名,它们会被当成多个参数传给同一次 rm——这正是我们要的批量效果。
二、处理带空格/特殊字符的文件名:必用 -0
find . -name "*.txt" -print0 | xargs -0 rm这是
xargs最容易出事的坑:文件名含空格时,默认按空格切分会把一个文件拆成"两个参数",rm 就会报"找不到文件"。解决就是成对使用find -print0(用 null 字符分隔输出)和xargs -0(按 null 读取)。只要文件是 find 出来的、名字又不可控,一律-print0 | xargs -0,这是铁律。
三、控制参数个数与占位:-n 与 -I
# -n:每次命令最多塞 N 个参数
find . -name "*.log" | xargs -n 1 gzip # 每个 log 单独一条 gzip
# -I:用占位符,把整行输入替换进去(适合命令位置不固定的场景)
find . -name "*.bak" | xargs -I{} mv {} /backup/
ls *.jpg | xargs -I% cp % /tmp/photos/
-n 1强制"一次一个",在每条都要独立执行的场景(比如逐文件打包)很有用。-I{}则是更通用的占位:后面的命令里写{},xargs 会用每行输入替换它。注意用了-I时默认一次只处理一行(隐含-L 1),不再是凑多个参数。
四、并行执行:-P
find . -name "*.png" | xargs -P 8 -I{} convert {} {}.jpg
-P N让xargs同时跑 N 个进程,多核机器上处理大量独立任务(压缩、转码、下载)时能显著提速——把 8 核都喂饱。但要确认任务之间无依赖、可并行,且注意把并发数控制在系统能承受的范围,别一上来-P 100把机器打挂。
五、确认再执行:-p 与 --verbose
find . -name "*.tmp" | xargs -p rm # 每执行一条都问 y/n
find . -name "*.tmp" | xargs -t rm # 执行前先打印要跑的命令批量删除/修改前,先
-t看一眼要执行的完整命令,或者-p逐条确认,能避免"一管道把所有文件删光"的惨剧。等价于 find 的"-exec 前先看清单"原则(见 find 详解)。
六、实战:批量压缩一周前的日志
# 找出 7 天前的 .log,逐个 gzip 压缩,8 路并行
find /var/log/app -name "*.log" -mtime +7 -print0 | xargs -0 -P 8 -I{} gzip {}这条命令把 find(按时间定位)+ xargs -0(安全传参)+ -P 8(并行)+ gzip(压缩)串成一行,是日志归档的标准动作。比写循环脚本短得多,也更好读。
一句话总结
xargs = 把管道输入转成命令参数的粘合剂:默认按空白切分拼成多参数;文件名不可控时务必 find -print0 | xargs -0 防空格拆裂;-n 限每次参数个数、-I{} 做整行占位、-P N 并行提速、-t/-p 执行前确认;与 find 组合是批量处理的基石,一行顶一段 for 循环。