【发布时间】:2010-04-16 23:09:52
【问题描述】:
我有一个 perl 脚本(或任何可执行文件)E,它将获取文件 foo.xml 并写入文件 foo.txt。我使用 Beowulf 集群为大量 XML 文件运行 E,但我想在 shell (bash) 中编写一个简单的作业服务器脚本,它不会覆盖现有的 txt 文件。
我目前正在做类似的事情
#!/bin/sh
PATTERN="[A-Z]*0[1-2][a-j]"; # this matches foo in all cases
todo=`ls *.xml | grep $PATTERN -o`;
isdone=`ls *.txt | grep $PATTERN -o`;
whatsleft=todo - isdone; # what's the unix magic?
#tack on the .xml prefix with sed or something
#and then call the job server;
jobserve E "$whatsleft";
然后我不知道如何区分 $todo 和 $isdone。我更喜欢使用 sort/uniq,而不是像里面有 grep 的 for 循环,但我不知道该怎么做(管道?临时文件?)
作为一个额外的问题,有没有办法在 bash grep 中进行前瞻搜索?
澄清/扩展问题:
我有一堆程序从(但不一定)data/{branch}/special/{pattern}.xml 等源获取输入并将输出写入另一个目录 results/special/{branch}-{pattern} .txt(或数据/{branch}/intermediate/{pattern}.dat,例如)。如果该文件已存在,我想检查我的 jobfarming shell 脚本。
例如,E 转换 data/{branch}/special/{pattern}.xml->results/special/{branch}-{pattern}.dat。我想查看输入的每个实例并检查输出是否存在。一种(公认更简单)的方法是触摸每个输入文件旁边的 *.done 文件并检查这些结果,但我宁愿不管理这些,有时作业会不正确地终止,所以我不想要它们标记完成。
注意我不需要检查并发性或锁定任何文件。
所以解决上述问题的一种简单明了的方法(在伪代码中)可能是
for i in `/bin/ls *.xml`
do
replace xml suffix with txt
if [that file exists]
add to whatsleft list
end
done
但我正在寻找更通用的东西。
【问题讨论】:
-
txtfile=${xmlfile%.xml}.txt替换 - 正如我的回答一样。 -
当你说“避免覆盖文件”时——我们需要并发意识吗?如果是这样,我们需要做一些锁定。 (如果是这样的话……我们是在共享文件系统上吗?哪个?它对
flock有适当的语义吗?) -
没有并发意识,还没有锁定 - 它是一个共享文件系统,但现在这是一个副项目
-
顺便说一句 - 如果您致力于使问题更加细化和独立,它将有助于 StackOverflow 作为知识库的质量。例如,“我如何获得以扩展名 A 开头而不是扩展名 B 的文件列表”,它很小且可重复使用;一旦问题包含有关您的特定用例的大量详细信息,其他人就更难找到并且更少使用。
标签: shell scripting grep replace