フルネームを持たない複数のファイルを処理する必要があります。 ifステートメントを実行するためにワイルドカードを使用しています。たとえば...
if [ "ESGSN_*.SMS.EDR" ]; then
echo "There are files to process in this run"
for F in ESGSN_*.SMS.EDR; do
gzip < "$F" > "$F.gz"
done
fi
複数のファイルまたは単一のファイルがあり、圧縮する場合に機能します。ただし、ファイルが存在しない場合は、直接終了せずにzipを実行し続けます。完了して続行する方法があるかどうか疑問に思います。
ファイル名の前の括弧内に「-f」および「-a」演算子を使用してみましたが、「バイナリ演算子が必要です」というエラーが発生します。
何らかの理由で、ファイル名のアスタリスクはメッセージの下に表示されません。したがって、ファイル名は "ESGSN_"*".SMS.EDR"で、二重引用符はアスタリスクです。
答え1
if ! gzip ESGSN_*.SMS.EDR 2>/dev/null; then
printf 'No files to process (gzip exit code: %d)\n' "$?"
fi
文字列ESGSN_*.SMS.EDR
が空ではないため、テストは常にtrueです。 globを二重引用符で囲むと*
処理されません。
また、ほとんどのシェルは、パターンが何も一致しない場合、デフォルトではパターンを拡張されていません。これは、コードが空のファイルを生成し、ESGSN_*.SMS.EDR.gz
パターンがファイル名と一致しない場合を呼び出すことを意味します。
上記のコードは、単にパターンに一致するすべてのファイルを圧縮しようとし、失敗した場合にメッセージを印刷します。
答え2
この質問に答える方法は2つあります。現在のスクリプトを修正するか、より速くより正確な選択肢を見つけることです。両方の方法を試してみましょう:)
まず、スクリプトの問題の1つは[ "ESGN_*.SMS.EDR" ]
常にtrueと評価されることです。この[ "<string>" ]
構成は、単に文字列が空でないかどうかをテストします。ファイルがなくても指定した文字列は空ではないため、テストは何もしません。
この問題を解決するには、すべてのファイルを繰り返してパターンと一致するかどうかをテストする必要があります。以下は私にとって効果的でした。
for F in *; do
if [[ "$F" =~ ESGSN_.*\.SMS\.EDR ]]; then
printf "Processing '%s'\n" "$F"
gzip < "$F" > "$F.gz"
fi
done
しかし、私がこの問題を自分の目的で解決したい場合は、そうしません。代わりにGNUを使用する方が速くて自然ですfind
。これにより、簡単なパターンマッチングが可能です。
find ./ -type f -regex ".*/ESGSN_.*\.SMS\.EDR" -exec bash -c "gzip < {} > {}.gz" \;
このfind
コマンドは非常に強力なので、Linuxを大量に使用している場合は慣れたいと思います。詳しく見ることをお勧めしますman find
。
答え3
みんなありがとうございます。私は以下から必要なものを手に入れることができました:
if ls -lrt ESGSN_*.SMS.EDR ; then
答え4
だから私はあなたのために少し単純化しました。
#!/bin/bash
shopt -s nullglob
files=(yourdir/*)
if [[ ${#files[@]} == 0 ]] # If array is equal to 0
then echo "No files there" >&2
exit 1
else
gzip "${files[@]}" # gzip all elements within the array.
fi
shopt -u nullglob
スクリプトの機能を説明してください。
設定nullglob
方法shopt -s nullglob
nullglob は、パターンに一致するファイルの数を計算するために使用されます。 nullglob がない場合、glob* はリテラル* に展開されます。つまり、空のディレクトリでは、数が常に1より大きく、誤った数が発生します。
nullglob
以下で設定を解除shopt -u nullglob
この行の後に潜在的に影響を受ける可能性のあるコードがさらにある場合、これは重要です
nullglob
。