如果输出已存在则跳过该行

如果输出已存在则跳过该行

我有一个在 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命令错误。

相关内容