web-dev-qa-db-ja.com

ターゲットファイルが存在しない場合にシェルスクリプトを終了する方法

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

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

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

次のようなファイルを使用して、ファイルの存在を確認できます。

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

does n't、のような場合に終了するには、次のようなもので十分です。

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

-f <file>は、使用できる多くの条件式のoneのみです。 CONDITIONAL EXPRESSIONSの下のbashマンページを見ると、それらのホスト全体が表示されます。


(質問の更新で述べたように)ワイルドカードの結果がファイルであるかどうかを確認したい場合は、単にそれを展開してエラーを破棄できます。存在しない場合は、-zで検出できる空の文字列になります。

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

Linux lsがデフォルトで出力デバイスが端末でない場合(メモリから)でも、-1を使用して行ごとに1つのファイルを強制していることに注意してください。これは、does n'tのマシンでこれを試してみて、その場合に1行に1つずつ強制する場合です。


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

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

ただし、knowでこれらの種類のファイルを使用することは決してない場合は、おそらくlsソリューションを使用してもかまいません。その欠点に満足していることを確認してください。

40
paxdiablo

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
_

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

しかしながら...

...おそらくfindを使用してファイルを取得することをお勧めします。

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

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

_{}_は、_do-something-to-filename_を呼び出すたびにファイル名に置き換えられます。

9
brice

私はこれを試してみましたが、これは私のために働いた

test -s <<your file path>> && exit 0 || <<things to do when file NOT exists>>

ファイルが存在しないときに実際に終了していることに注意してください

0
Kishan B

find ... -exec ...またはfind ... -print0 | xargs -0 ...は通常は問題ありませんが、bashのnullglobオプションを使用して、globで直接実行できます。

bash-3.2$ echo *foo
*foo
bash-3.2$ shopt -s nullglob
bash-3.2$ echo *foo

bash-3.2$ 

スクリプトの残りの部分に応じて、shopt -u nullglobを使用して再設定したい場合としない場合があります。

0
Kevin