同じ文字列/パターンで終わるファイルがあるかどうかを確認するのに問題があります。ファイル名は次のようになります。
abs_123.unl
xyz_123.unl
現在私のコードは次のとおりです。単一ファイルでは正常に動作しますが、同じパターンのファイルが複数ある場合、if条件は失敗します。
if [ -s $AZWORK/*$PRCSID.unl ]
then
tar -cvzf $WORK/INET_$PRCSID.unl.gz $WORK/*$PRCSID.unl
fi
ここで、$PCSID はファイルの最後の 3 桁を表します。
このシェルスクリプトを複数のファイルで動作させるにはどうすればよいですか?
答え1
ファイルの「検索」と「サイズの調整」を次のユーザーに委任しますfind
。
find "$WORK" -maxdepth 1 -name "*$PRCSID.unl" -type f ! -size 0 -print0 | \
xargs -0 --no-run-if-empty tar -cvzf "$WORK/INET_$PRCSID.unl.gz"
"*_123.unl"
これにより、そのパターンが存在する可能性があるサブディレクトリをフィルタリングすることもできます。
オプションfind
:
-maxdepth 1
サブディレクトリへの再帰防止-name "*$PRCSID.unl"
*
シェルの拡張を防ぐために、ファイル名を引用してファイル名と一致させます。-type f
ファイルのみ! -size 0
サイズが大事です!-print0
NULで区切られた名前を印刷します。ここでは必ずしも必要ではありませんが、ファイル名に改行文字が含まれていても問題になりません。
オプション/パラメータxargs
:
-0
stdinがNULで区切られているとします(改行で区切られていません)。--no-run-if-empty
標準入力にデータがない場合は実行されません(つまり、findには出力があります)。- 残りの行は、実行するコマンドでstdinのデータを引数として追加します。
答え2
簡単にこれを行うことができます:
tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID.unl"
答え3
パターンに一致するファイルがあるかどうかを確認するには、次のようにします。
もし["$(shopt -s nullglob; printf "%s" "$WORK"/*"$PRCSID".unl)" != ""] それから tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl フィリピン諸島
.unl
(ある場所でファイルを見つけ、別の場所に保存する予定はないとします。)
shopt -s nullglob
ファイル名パターンに一致するエントリがない場合、ファイル名パターンは何も「拡張」されないため、作業ディレクトリに名前がitで終わるファイルがない場合、123.unl
文字列引数は"$WORK"/*"$PRCSID".unl
消えprintf
、印刷する項目は残りません。
メモ:
shopt -s nullglob
たとえば、external宣言を使用できますif
。shopt -s nullglob #おそらくスクリプトの他の場所にあるかもしれません。 ⋮ if [ "$(printf "%s" "$WORK"/*"$PRCSID".unl)" != "" ] それから tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl フィリピン諸島
スクリプトを実行してこの動作(一致しないパターンの空の拡張)を有効にしたい場合。- 特別な理由がない限り、常にシェル変数(例:
"$WORK"
and)を引用する必要があります。"$PRCSID"
確かにあなたは何をしているのか知っています。変数を参照するだけで断片的に実行できます。"$WORK"/*"$PRCSID".unl および "$WORK"/INET_"$PRCSID".unl.gz
または、変数を含む単語全体を引用することもできます。たとえば、次のようになります。"$WORK/"*"$PRCSID.unl" および "$WORK/INET_$PCSID.unl.gz"
"$WORK/*$PRCSID.unl"
ただし、これにより、*
ファイル名拡張パターン(ワイルドカードやglobなど)で機能しないように引用符で囲むことができます。 - ファイル名パターンは制御可能なディレクトリ名で始まるため、特にフルパス(で始まる
/
)である場合、または少なくとも保証できます。いいえ最初-
echo
) - そうであれば、IEを使用しても安全ですprintf "%s"
。もし["$(shopt -s nullglob;エコ"$WORK"/*"$PRCSID".unl)" != "" ] それから tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl フィリピン諸島
もちろん、ここの声明からshopt -s nullglob
この内容を削除することもできます。if
別の方法
もしあなたなら必要if
たとえば、ステータス/ログ/エラーメッセージを作成するには、- then
- else
(または少なくともif
-)を持つにはthen
上記の方法を使用する必要があります。ただし、tar
ファイルがある場合にのみコマンドを実行することが唯一の関心事であれば、省略してif
実行then
できます。
(shopt -s障害グローバル。tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unl)
shopt -s failglob
つまり、ファイル名パターンと一致しないファイル名パターンを含む引数を使用してコマンドを実行しようとすると、
コマンドは実行されませんでした。。上記は、あなたの質問のコードが達成したいことを正確に行います。tar
作業ディレクトリに名前で終わるファイルがある場合はコマンドを実行し、123.unl
それ以外の場合は実行しません。
shopt -s failglob
同様に、コマンドとコマンドを分離できますtar
。
shopt -s 障害グローバル #おそらくスクリプトの他の場所にあるかもしれません。 ⋮ tar -cvzf "$WORK/INET_$PRCSID.unl.gz" "$WORK"/*"$PRCSID".unlスクリプトを実行してその動作を達成したい場合(一致しないパターンでコマンドを実行しない)
答え4
find
コマンドは必要なファイルを検索し、次の結果に対してコマンドを実行できます。
find $WORK -name *.unl -exec tar -zcvf $WORK/INET_$PRCSID.unl.gz {} \;