2

単純な bash スクリプトを実行しようとしていますが、条件を統合する方法に苦労しています。任意のポインター。ループは言います。gdalinfo がイメージを開くことができない場合に、その特定のファイルを別の場所にコピーするような条件を組み込みたいと思います。

for file in `cat path.txt`; do gdalinfo $file;done

画像を開く際に正常に機能し、開くことができない画像も表示されます。
間違ったコードは

for file in `cat path.txt`; do gdalinfo $file && echo $file; else cp $file /data/temp
4

2 に答える 2

6

何度も何度も - ジリオン th また...

次のような構造を使用しないでください

for file in `cat path.txt`

また

for file in `find .....`
for file in `any command what produces filenames`

ファイル名またはパスにスペースが含まれていると、コードがすぐに壊れるためです。ファイル名を生成するコマンドには絶対に使用しないでください。悪い習慣。ひどい。それは間違っている、間違っている、誤っている、不正確である、不正確である、不正確である、不完全である、間違っている。

正しい形式は次のとおりです。

for file in some/*   #if want/can use filenames directly from the filesystem

また

find . -print0 | while IFS= read -r -d '' file

または(ファイル名に改行が含まれていないことが確実な場合)使用できます

cat path.txt | while read -r file

しかし、ここでは役に立ちません(実際には、ファイルをSTDOUTにコピーするだけcatのコマンド役に立ちません)。代わりに使用する必要があります

while read -r file
do
   #whatever
done < path.txt

高速です (すべてのパイプの場合のように、新しいプロセスをフォークしません)。

上記whileの s はfile、ファイル名にスペースも含まれている場合に、正しいファイル名を変数に入力します。for しません。限目。うーん。ああ、神様。

同じ理由"$variable_with_filename"で純粋の代わりに使用します。$variable_with_filenameファイル名に空白が含まれている場合、コマンドはそれを 2 つのファイル名と誤解します。これはおそらくそうではありません、あなたも欲しいもの..

そのため、ファイル名を含むシェル変数は二重引用符で囲みます。(ファイル名だけでなく、スペースを含むものすべて)。"$variable"正しい。

私が正しく理解していれば、エラーが返され/data/tempたときにファイルをコピーする必要があります。gdalinfo

while read -r file
do
   gdalinfo "$file" || cp "$file" /data/temp
done < path.txt

素晴らしく、短く、安全です (少なくとも、path.txt に実際に 1 行に 1 つのファイル名が含まれている場合)。

また、スクリプトをより多く使用したい場合は、ファイル名を内部に含めずに、スクリプトをフォームに保存します。

while read -r file
do
   gdalinfo "$file" || cp "$file" /data/temp
done

次のように使用します。

mygdalinfo < path.txt

より普遍的な...

gdalinfoおそらく、エラーを返すもののファイル名のみを表示したい

while read -r file
do
   gdalinfo "$file" || printf "$file\n"
done

をに変更するprintf "$file\n"printf "$file\0"、スクリプトをパイプで安全に使用できるようになります。

while read -r file
do
   gdalinfo "$file" || printf "$file\0"
done

たとえば、次のように使用します。

 mygdalinfo < path.txt | xargs -0 -J% mv % /tmp/somewhere

なんて。

于 2013-07-19T11:35:26.117 に答える
1

あなたは言うことができます:

for file in `cat path.txt`; do gdalinfo $file || cp $file /data/temp; done

/data/tempこれにより、gdalinfo がイメージを開くことができない場合にファイルがコピーされます。

失敗した場合にファイル名をコピーするだけでなく、ファイル名を印刷したい場合は、次のように言います。

for file in `cat path.txt`; do gdalinfo $file || (echo $file && cp $file /data/temp); done
于 2013-07-19T11:07:43.360 に答える