以下のスクリプトを考えると、ファイルが存在しない場合はパイプラインの実行を避けたいと思います。
テキスト ファイルが見つからない場合、スクリプトをすぐに終了するにはどうすればよいですか?
ls */*.txt | grep ab1 | awk '{print $1, $1}' | sed "s/\"/\"\"/g" | xargs -L1 mv
次のような方法でファイルの存在を確認できます。
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>
にすぎません。の下のマンページを見ると、それらのホスト全体が表示されます。bash
CONDITIONAL EXPRESSIONS
(質問の更新で述べたように)ワイルドカードがファイルになるかどうかを確認したい場合は、単に展開してエラーを捨てることができます。何もない場合は、次のように検出できる空の文字列になります-z
。
if [[ -z "$(ls -1 */*.txt 2>/dev/null | grep ab1)" ]] ; then
echo 'There are no "*/*.txt" files.'
exit
fi
出力デバイスが(メモリからの)端末でない場合、-1
Linuxはデフォルトで強制的に1行に1つのファイルを強制していましたが、以前は1行に1つのファイルを強制していたことに注意してください。これは、その場合に行ごとに強制しないls
マシンでこれを試す場合に備えてです。
ただし、ファイル名にスペースが含まれている場合、ls
and を使用しawk
て列 1 を抽出してもうまくいかないことに注意してください。たとえば、ファイルはビットabc ab1.txt
のみの抽出になります。abc
withfind
と with-print0
を組み合わせて使用することは、「特殊」文字を含む可能性のあるファイルを適切に処理する通常の方法です。必要なファイルのみが処理されるようにするために指定できるオプションは他にもたくさんあります。たとえば、ディレクトリ ツリーのどこまで進むかを制限したり、ファイル名を適切にフィルター処理したりできます。xargs
-0
find
-maxdepth
-name
ただし、これらの種類のファイルが決してないことがわかっている場合は、おそらくls
ソリューションを使用しても問題ありませんが、その欠点に慣れていることを確認してください.
test
存在をテストするための迅速で短い方法:
test -e $FILENAME || exit
次のようにしてチェーンできます。
test -e $FILENAME && something | something-else
その場合something
、something-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
。