带有标准输入/标准输出重定向的 xargs

Nik*_*hhi 27 io-redirection xargs

我想运行:

./a.out < x.dat > x.ans
Run Code Online (Sandbox Code Playgroud)

对于目录A中的每个 * .dat文件。

当然,它可以通过 bash/python/任何脚本来完成,但我喜欢写性感的单行。我所能达到的只有(仍然没有任何标准输出):

ls A/*.dat | xargs -I file -a file ./a.out
Run Code Online (Sandbox Code Playgroud)

但是-axargs 中的不理解 replace-str 'file'。

谢谢你的帮助。

roz*_*acz 36

首先,不要将ls输出用作文件列表。使用外壳扩展或find. 请参阅下面的ls+xargs误用的潜在后果和正确xargs使用的示例。

1.简单方法:for循环

如果您只想处理 下的文件A/,那么一个简单的for循环就足够了:

for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
Run Code Online (Sandbox Code Playgroud)

2. pre1为什么不   ls | xargs 呢?

这是一个示例,说明如果您使用lswithxargs来完成工作,事情可能会变得多么糟糕。考虑以下场景:

所以你刚刚设法覆盖了mypreciousfile.datmypreciousfile.dat.ans。如果这些文件中有任何内容,它就会被删除。


2.使用  xargs :正确的方式  find 

如果您想坚持使用xargs,请使用-0(null-terminated names) :

find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
Run Code Online (Sandbox Code Playgroud)

注意两点:

  1. 这样你就可以创建带有.dat.ans结尾的文件;
  2. 如果某些文件名包含引号 ( ),这将中断"

这两个问题都可以通过不同的shell调用方式来解决:

find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
Run Code Online (Sandbox Code Playgroud)

3. 全部完成 find ... -exec

 find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
Run Code Online (Sandbox Code Playgroud)

这再次产生.dat.ans文件,如果文件名包含". 为此,请使用bash并更改调用方式:

 find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;
Run Code Online (Sandbox Code Playgroud)

  • +1 提及不解析 ls 的输出。 (2认同)
  • 当文件名包含“. (2认同)
  • 很好的观点,谢谢!我会相应地更新。 (2认同)