xargs 与 stdin/stdout 重定向

xargs 与 stdin/stdout 重定向

我想运行:

./a.out < x.dat > x.ans

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

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

ls A/*.dat | xargs -I file -a file ./a.out

-A在 xargs 中不理解replace-str '文件'。

谢谢你的帮助。

答案1

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

1、简单的方法:为了环形

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

for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done

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

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

  • 首先,让我们创建一些空文件:

    $ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
    $ touch A/mypreciousfile.dat
    $ touch A/mypreciousfile.dat.ans
    
  • 查看这些文件,发现它们不包含任何内容:

    $ ls -1 A/
    mypreciousfile.dat
    mypreciousfile.dat with junk at the end.dat
    mypreciousfile.dat.ans
    
    $ cat A/*
    
  • 使用以下命令运行魔术命令xargs

    $ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
    
  • 结果:

    $ cat A/mypreciousfile.dat
    TRICKED with junk at the end.dat.ans
    
    $ cat A/mypreciousfile.dat.ans
    TRICKED
    

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


2. 使用方法  xargs :正确使用方法  find 

如果您想坚持使用xargs,请使用-0(以空字符结尾的名称) :

find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'

注意两件事:

  1. 这样你就可以创建以.dat.ans结尾的文件;
  2. 会打破如果某个文件名包含引号 ( ")。

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

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

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

 find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;

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

 find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;

答案2

使用 GNU 并行:

parallel ./a.out "<{} >{.}.ans" ::: A/*.dat

额外的好处:您可以并行完成处理。

观看介绍视频以了解更多信息:http://www.youtube.com/watch?v=OpaiGYxkSuQ

答案3

尝试做这样的事情(语法可能会有所不同,具体取决于您使用的 shell):

$ for i in $(find A/ -name \*.dat); do ./a.out < ${i} > ${i%.dat}.ans; done

答案4

我认为您至少需要在 xargs 中进行 shell 调用:

ls A/*.dat | xargs -I file sh -c "./a.out < file > file.ans"

编辑:应该注意的是,当文件名包含空格时,此方法不起作用。无法工作。即使您使用 find -0 和 xargs -0 来使 xargs 正确理解空格,-c shell 调用也会对它们发出嘎嘎声。然而,OP 明确要求 xargs 解决方案,这是我想出的最好的 xargs 解决方案。如果文件名中的空格可能是问题,请使用 find -exec 或 shell 循环。

相关内容