我想运行:
./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
?
下面是一个示例,说明如果您使用ls
withxargs
来完成这项工作,事情可能会变得多么糟糕。考虑以下场景:
首先,让我们创建一些空文件:
$ 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.dat
和mypreciousfile.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"'
注意两件事:
- 这样你就可以创建以
.dat.ans
结尾的文件; - 这会打破如果某个文件名包含引号 (
"
)。
这两个问题都可以通过不同的 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 循环。