跳转到内容

xargs

xargs 用于将前一个命令的标准输出转换为后一个命令的命令行参数,解决了许多命令(如 rm、cp、mv)不支持从标准输入读取参数的问题。

Terminal window
command1 | xargs command2

等价于:

Terminal window
command2 arg1 arg2 arg3 ...
选项 作用
-n N 每次传 N 个参数(可用于控制批处理)
-0 和 find -print0 一起用,安全处理文件名中的空格/特殊字符
-I {} 指定替换占位符,用 {} 表示输入的每一项
-P N / --max-procs=N 多进程并行执行,加快执行速度

1. 每次传 N 个参数(-n)

Terminal window
echo "a b c d" | xargs -n 2 echo

将 a b c d 分成每 2 个一组来执行:

Terminal window
echo a b
echo c d

输出:

a b
c d

2. 用 null 字符作为分隔符(-0)

Terminal window
find . -name "*.txt" -print0 | xargs -0 rm
  • find -print0:输出文件名之间用空字符 \0 分隔(而不是换行)
  • xargs -0:按 \0 读取参数,避免空格、特殊字符导致参数被错误拆分

避免出现如下情况:

# 文件名
my file.txt
otherfile.txt
# 不使用 -print0 和 -0
find . -name "*.txt" | xargs rm
# 等价于
rm ./my
rm file.txt
rm ./otherfile.txt
# 使用 -print0 和 -0
find . -name "*.txt" -print0 | xargs -0 rm
# 等价于
rm "my file.txt" "otherfile.txt"

3. 将输入项替换到命令中指定位置(-I {})

Terminal window
echo "file1 file2 file3" | xargs -I {} cp {} /backup/

把每个文件名 {} 替换到 cp {} 中执行:

  • cp file1 /backup/
  • cp file2 /backup/
  • cp file3 /backup/

-I {} 会隐式地让 xargs 每次只处理一个参数,默认 -n 1

4. 并行执行命令(-P)

Terminal window
cat urls.txt | xargs -n 1 -P 4 curl -O
  • 每次用 1 个 URL(-n 1)
  • 同时最多开启 4 个并发下载(-P 4)

相当于并发执行:

Terminal window
curl -O <url1> # 第 1 个 URL
curl -O <url2> # 第 2 个 URL
curl -O <url3> # 第 3 个 URL
curl -O <url4> # 第 4 个 URL

核心区别:命令是否支持从标准输入(stdin)读取参数。

方法 是否通用 参数传递方式 适用情况
管道传参(cmd1 | cmd2) 否 不是所有命令都支持 把上一条命令的输出作为标准输入
xargs 传参(cmd1 | xargs cmd2) 是 适用于大多数命令 把前一个命令的输出作为命令行参数

举例区分:

Terminal window
# 管道直接传给 rm:不起作用!rm 不接受标准输入
find . -name "*.log" | rm # 错误
# 使用 xargs:正确
find . -name "*.log" | xargs rm

总结:

方法 特点 适用命令类型
管道直接传 通过 stdin 输入 grep、sort、awk、cat、less 等
xargs 把输入转为参数 rm、cp、mv、mkdir、echo 等