私は何を見逃していますか?
ディレクトリ内のファイルのうち、指定されたパターンに一致するファイル数を見つけて変数に割り当てたいと思います。
コマンドラインに直接入力すると正常に動作します。
ls /backups/system\ db\ files/temp/daily/backup_filename_202203*.tar.gz | wc -l
(注:これは*
バックアップが作成された日です。01
など)02
03
しかし、一度bashスクリプトに追加すると失敗します。
これまで私は以下を持っています:
base_dir="/backups/system\ db\ files/temp"
sub_dir="${base_dir}/daily"
filename_base="backup_filename_"
その後、次を実行しようとします。
counter=$(ls ${sub_dir}/${filename_base_}202203*.tar.gz | wc -l)
または引用符で:
counter=$(ls "${sub_dir}/${filename_base_}202203*.tar.gz" | wc -l)
1 つ目は、スペースに基づいて分割しようとするため失敗します。 2番目はワイルドカード文字を見つけるために拡張されません*
。
私はそれらのいくつかを引用してみました。
counter=$(ls "${sub_dir}/${filename_base_}"202203*.tar.gz | wc -l)
しかし今回もワイルドカードを無視します。
探していますが、一致するファイルの総数を取得する方法を一生見つけることはできません。
答え1
問題は、ディレクトリが呼び出されないことです/backups/system\ db\ files/temp
。backups/system db files/temp
文字列を引用すると、バックスラッシュは文字列の一部になります。文字列を引用したので、スペースをエスケープする必要はありません。filename_base
また、変数のスペルが複数の場所で間違っています(末尾の下線を含む)。
また、シェルパターンに一致する名前の数を使用しls
て計算する必要もありません。wc
ファイル名には改行文字を含めることができ、wc -l
ファイル名ではなく改行文字のみを計算します。
シェルパターンに一致する項目がいくつあるかを確認するには、パターンを配列または位置引数のリストに展開してから、その配列またはリストの長さを確認するだけです。
サンプルパターンで配列を使用する:
list=( "some/path to the/files"/*.txt )
count=${#list[@]}
位置引数リストを使用します。
set -- "some/path to the/files"/*.txt
count=$#
bash
シェルでは、空のディレクトリを適切に処理するnullglob
ためにシェルオプションを設定する必要がありますshopt -s nullglob
(パターンが何も一致しない場合、通常パターンは拡張されません)。
設定されていない場合は、nullglob
次のコマンドを使用して一致するものがないかどうかをテストできます。
list=( "some/path to the/files"/*.txt )
count=${#list[@]}
if [ ! -e "${list[0]}" ] && [ ! -h "${list[0]}" ]; then
count=0
fi
または位置パラメータを使用する場合
set -- "some/path to the/files"/*.txt
count=$#
if [ ! -e "$1" ] && [ ! -h "$1" ]; then
count=0
fi
否定され、テストが次のような-e
場合-h
本物結果リストの最初の要素の場合、最初の要素は既存のファイルや壊れたシンボリックリンクではありません。これは、パターンに一致する項目がないことを意味します。
答え2
引用の際にスペースを抜かないでください。それ以外の場合、バックスラッシュは文字通り使用されます。
base_dir="/backups/system\ db\ files/temp"
しなければならない
base_dir="/backups/system db files/temp"
そして、_
なぜそれを持っていますか${filename_base_}
?
最後のコマンドではおそらく他のすべてが正しい場合は、次のように動作します。
counter=$(ls "${sub_dir}/${filename_base}"202203*.tar.gz | wc -l)
とにかくあなたは解析しないでくださいls
。
代わりに、以下を使用してくださいfind
。
find "${sub_dir}" -name "${filename_base}202203*.tar.gz" -printf '.' | wc -c
または配列:
shopt -s nullglob
files=("${sub_dir}/${filename_base}"202203*.tar.gz)
echo "${#files[@]}"
このオプションが必要です。それ以外の場合、文字列は文字通り処理されるため、パターンに一致するファイルがなくなりnullglob
ます。1