34

以下のスクリプトを考えると、ファイルが存在しない場合はパイプラインの実行を避けたいと思います。

テキスト ファイルが見つからない場合、スクリプトをすぐに終了するにはどうすればよいですか?

ls */*.txt | grep ab1 | awk '{print $1, $1}' | sed "s/\"/\"\"/g" | xargs -L1 mv
4

4 に答える 4

59

次のような方法でファイルの存在を確認できます。

if [[ -f x.txt ]] ; then
    echo file exists.
fi

そうでない場合に終了するには、次のようなもので十分です。

if [[ ! -f x.txt ]] ; then
    echo 'File "x.txt" is not there, aborting.'
    exit
fi

これは、使用できる多くの条件式の1 つ-f <file>にすぎません。の下のマンページを見ると、それらのホスト全体が表示されます。bashCONDITIONAL EXPRESSIONS


(質問の更新で述べたように)ワイルドカードがファイルになるかどうかを確認したい場合は、単に展開してエラーを捨てることができます。何もない場合は、次のように検出できる空の文字列になります-z

if [[ -z "$(ls -1 */*.txt 2>/dev/null | grep ab1)" ]] ; then
    echo 'There are no "*/*.txt" files.'
    exit
fi

出力デバイスが(メモリからの)端末でない場合、-1Linuxはデフォルトで強制的に1行に1つのファイルを強制していましたが、以前は1行に1つのファイルを強制していたことに注意してください。これは、その場合に行ごとに強制しないlsマシンでこれを試す場合に備えてです。


ただし、ファイル名にスペースが含まれている場合、lsand を使用しawkて列 1 を抽出してもうまくいかないことに注意してください。たとえば、ファイルはビットabc ab1.txtのみの抽出になります。abc

withfindと with-print0を組み合わせて使用​​することは、「特殊」文字を含む可能性のあるファイルを適切に処理する通常の方法です。必要なファイルのみが処理されるようにするために指定できるオプションは他にもたくさんあります。たとえば、ディレクトリ ツリーのどこまで進むかを制限したり、ファイル名を適切にフィルター処理したりできます。xargs-0find-maxdepth-name

ただし、これらの種類のファイルが決してないことがわかっている場合は、おそらくlsソリューションを使用しても問題ありませんが、その欠点に慣れていることを確認してください.

于 2013-05-30T01:45:50.883 に答える
19

使用するtest

存在をテストするための迅速で短い方法:

test -e $FILENAME || exit

次のようにしてチェーンできます。

test -e $FILENAME && something | something-else 

その場合somethingsomething-elseファイルが存在する場合にのみ実行されます。

例えば:

➤ test -e ~/.bashrc && echo True || echo False
True
➤ test -e ./exists-not && echo True || echo False
False

余談:[は のエイリアスであることに注意してくださいtest。のセマンティクスはbash によって定義されており、bash のマンページ[[で見つけることができます

でも...

find...ファイルを取得するために使用する方がおそらく良いでしょう:

find ./ -maxdepth 2 -name "*ab1*.txt" -exec do-something-to-filename '{}' \;

の出力をls確実に解析できないためです。これは、ファイル名が存在する場合にのみコマンドを実行しdo-something-to-filenameます。これは、あなたがやろうとしていると思います。

{}を呼び出すたびにファイル名に置き換えられますdo-something-to-filename

于 2013-05-30T01:48:59.980 に答える