txtファイルの各行で特定のタスクを実行し、最後に各行の出力ファイルを生成するCentOSコンピュータで実行されるスクリプトがあります。スクリプトが停止して再実行する必要があるが、出力ファイルがすでに生成されたファイル行を繰り返さないオプションを追加します。どうすればいいですか?
スクリプトは次のとおりです。
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.netcd
はスクリプトの整合性を確認するための優れたツールであり、引用符なしの変数参照や未確認のコマンドエラーなどの一般的なエラーを指摘しています。