私は特定のフォルダ内のファイル(この場合はそのフォルダ内のすべての.csvファイル)を削除する非常に単純なシェルを作成しています。
コードは次のとおりです。
#!/bin/bash
# Used to clean folder
MinVal=0
Files=$(ls -1 *.csv | wc -l)
if [ $Files -gt $MinVal ];then
rm *.csv
echo -e "\e[31;43m***** DONE *****\e[0m"
else
echo -e "\e[31;43mThere is no valid file to delete, please check\e[0m"
fi
シェルスクリプトは期待どおりに機能しますが、シェルを実行してフォルダに.csvファイルがない場合、端末に次のように表示されます。
ls: cannot access *.csv: No such file or directory
もちろん、次のelse
メッセージも表示されます。
There is no valid file to delete, please check
これを回避し、エラー処理をls: cannot access *.csv: No such file or directory
直接実行する方法はありますか?else
挨拶。
答え1
これは、シェルが*.csv
デフォルトのPOSIX動作のままに渡されるために発生します。ls
これを回避するには、nullglob
入力の軸文字列を返すのではなく、何も返さないglobを使用する必要があります。しかし、ここには問題があります。ls
ファイルが提供されない場合は動作が異なるためです。
ファイル名に改行文字が含まれている場合は、エラーを回避する利点がある次の方法を試してください。
shopt -s nullglob
filenames=( *.csv ) # put all files in an array
files="${#filenames[@]}" # get number of files
答え2
警告メッセージを表示したくない場合は、ls
最も簡単な方法はにリダイレクトすることですstderr
。/dev/null
たとえば、次のようになります。
Files=$(2>/dev/null ls -1 *.csv | wc -l)
リダイレクトはstderr
抑制されます。みんな*.csv
ディレクトリ内の欠落しているファイルに関連しない可能性があるエラーを含む、このコマンドによって発生したエラー。
ファイル数を数えるより良い解決策は、次のように代わりにfind
使用することですls
。
find . -maxdepth 1 -name "*.csv" | wc -l
実際には、以下を使用して削除を実行することもできますfind
。
find . -maxdepth 1 -name "*.csv" -delete
私もあなたが-r
フラグを使用したことに気づきました。これは、を使用して単純検索を行った後、を使用して再帰削除をrm
実行したため、意図しないように見えます。ls
rm
しかし、正直なところ、これをスクリプトで書くのは妥当ではないと思います。コマンドを直接実行するのと比較して、このスクリプトの利点は何ですか?つまり、これが何が問題なのか:
# Check for files
ls *.csv
# Delete the files
rm *.csv
これらのコマンドを実行するよりもスクリプトを実行する方が良いのはなぜですか?オーバーヘッドを追加し、あるエラーメッセージを別のエラーメッセージに置き換えるようです。