默认情况下xargs
将连接多行输入并将其传递给指定的命令。例如:
echo -e 'line 1\nline 2\nline 3' | xargs echo
结果是
line 1 line 2 line 3
因为参数被发送到单个 echo 命令(在命令行长度的限制内)。
有时您想使用替换字符串将参数放在命令中的其他位置,而不是末尾:
echo -e 'line 1\nline 2\nline 3' | xargs -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE
现在,xargs 只会在每次 echo 调用中替换一个参数,因为手册页上说“-I 意味着 -L 1...”。这可能是典型情况下的正确行为,但有没有办法覆盖它,以便我得到line 1 line 2 line 3 DONE
输出?
请注意,我的例子仅供参考 - 我对使用非 xargs 方法来解决这个问题不太感兴趣。
答案1
我不知道有什么xargs
选项可以做到这一点,但你可以通过以下调用实现类似的功能bash -c
:
$ echo -e "line 1\nline 2\nline 3" | xargs bash -c 'echo "${@}" DONE' _
line 1 line 2 line 3 DONE
请注意,xargs
不提供线作为参数,即使您指定了-L
。您可能希望使用来-d
指定换行符分隔项目(我相信仅限 gnu xargs)。对比以下内容:
$ echo -e "line 1\nline 2\nline 3" |
xargs bash -c 'printf "<%s>\n" "${@}" DONE' _
<line>
<1>
<line>
<2>
<line>
<3>
<DONE>
$ echo -e "line 1\nline 2\nline 3" |
xargs -d\\n bash -c 'printf "<%s>\n" "${@}" DONE' _
<line 1>
<line 2>
<line 3>
<DONE>
答案2
将换行符转换为\nul
终止符,然后使用xargs -0
$ echo -ne 'line 1\nline 2\nline 3\n' | tr '\n' '\0' | xargs -0 -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE
答案3
这个怎么样:
arg=$( echo -e 'line 1\nline 2\nline 3' | xargs )
echo $arg Done.
我使用这个构造从多个单个 PDF 生成一个多页 PDF 文件:
arg=$( find -mmin -60 -type f -name "*.pdf" | xargs )
pdftk $arg cat output AllMyRecentPDFs.pdf
答案4
如果我理解你的问题,我认为你只是想将换行符转换为非分隔符。
echo -ne'foo\nbar\nbaz'|tr'\n'''|xargs -I{} echo {}完成