xargs 的 -I 占位符支持单输入项多处替换,配合 -print0/-0 可安全处理含空格文件名,常用于单文件双目标复制;-I 与 -n/-L 不兼容,需用 -P 实现并发。

用 xargs 的 -I 占位符,可以在一条命令中对同一个输入项执行多步操作,比如把一个文件同时复制(或移动)到两个不同目录。关键在于:占位符(如 {} 或 %)在命令中可多次出现,xargs 会将其统一替换为当前处理的文件名。
用 -I {} 实现单文件双目标分发
假设你想把 find 找到的每个 .log 文件,同时复制到 /backup/ 和 /archive/ 目录:
- 必须使用
-I指定占位符,否则无法重复引用同一参数 - 占位符在命令中出现几次,就替换几次,位置不限(开头、中间、结尾均可)
- 推荐用
cp而非mv,避免误删原文件;若确需移动,确保逻辑无歧义
示例命令:
find . -name "*.log" -print0 | xargs -0 -I {} sh -c 'cp "{}" /backup/ && cp "{}" /archive/'
安全前提:处理含空格/特殊字符的文件名
直接用默认空格分隔会出错,尤其当文件名含空格、换行或括号时。必须配合 -print0 + -0:
-
find ... -print0让每个文件名以\0结尾 -
xargs -0告诉它按\0切分,而非空格 - 占位符本身不解决分隔问题,
-0才是安全基础
替代写法:用 sh -c 封装更清晰的逻辑
当操作变复杂(比如加判断、日志、错误检查),建议显式调用 shell:
find /var/log -name "app_*.log" -mtime +7 -print0 | \
xargs -0 -I {} sh -c 'echo "Copying {}"; cp "$1" /safe/ "$1".bak' _ {}
- 这里用
sh -c '...' _ {}形式,把{}作为位置参数$1传入 -
_是占位符,代表$0(脚本名),避免{}被误当作$0 - 双引号包裹
"$1"可防止路径展开失败,比裸写{}更健壮
注意:-I 与 -n/-L 不兼容,慎用并发
-I 模式下,xargs 默认逐个执行(每个输入触发一次命令),不支持 -n 或 -L 分组。若想并发,需用 -P:
-
xargs -0 -P 4 -I {} cp "{}" /dst1/ "{}".copy—— 最多 4 个cp并行 - 但要注意目标目录是否支持并发写入,避免冲突
- 不加
-P时就是串行,适合需要顺序保障的操作

















