我有一个在 CentOS 机器上运行的脚本,它对 txt 文件的每一行执行某些操作,最后为每一行生成一个输出文件。脚本已停止,我应该再次运行它,但添加一个选项,不对已创建输出文件的文件行重复操作。我怎样才能做到这一点?
这是脚本:
while IFS=READ -r file; do
dir1=${file: -5:1}
dir2=${file#*_*_}
protein=$dir2.pdb
pock=$file.pdb
output=$file.txt
cd $dir1
cd $dir2
/path/to/executable -ps -i $protein -gl $pock -o /path/to/$output
cd ..
cd ..
done < /path/to/input.txt
答案1
首先,正如 terdon 在评论中指出的那样,在IFS=
和之间需要一个空格read
(并且read
命令应该是小写):
while IFS= read -r file; do
现在,对于您的实际问题:如果目标是在输出文件已存在的情况下跳过,您可以在设置之后output
但在cd
命令之前将其添加到循环中:
if [ -e "/path/to/$output" ]; then
continue # the output file already exists, so skip re-creating it
fi
该continue
命令将跳过循环迭代的其余部分,直接进入列表中的下一行/文件。顺便说一句,请注意,我在路径两边加上了双引号,因为它包含变量引用。双引号变量引用几乎总是一个好主意。
如果可能的话,我还建议避免cd
在脚本中使用;如果由于任何原因失败,脚本的其余部分将变得混乱并在错误的目录中运行。如果可以的话,只需使用显式路径:
/path/to/executable -ps -i "$dir1/$dir2/$protein" -gl "$dir1/$dir2/$pock" -o "/path/to/$output"
如果由于某种原因这不起作用(例如可执行文件的工作目录实际上必须是文件所在的目录),至少只执行一个cd
命令,如果失败,不要尝试执行或cd
返回,因为它是不会工作:
if ! cd "$dir1/$dir2"; then
echo "Error changing into $dir1/$dir2; we're going to have to skip this one." >&2
continue # skip ahead to the next line/file
fi
/path/to/executable -ps -i "$protein" -gl "$pock" -o "/path/to/$output"
if ! cd ../..; then
echo "Error getting back to main directory. Unable to continue" >&2
exit 1
fi
顺便提一句,shellcheck.net是检查脚本完整性的好工具,并且会指出常见错误,例如未双引号变量引用和未检查cd
命令错误。