ディレクトリに複数のファイルがあることを確認し、同じファイルを圧縮する方法

ディレクトリに複数のファイルがあることを確認し、同じファイルを圧縮する方法

同じ文字列/パターンで終わるファイルがあるかどうかを確認するのに問題があります。ファイル名は次のようになります。

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サイズが大事です!
  • -print0NULで区切られた名前を印刷します。ここでは必ずしも必要ではありませんが、ファイル名に改行文字が含まれていても問題になりません。

オプション/パラメータxargs

  • -0stdinが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 {} \;

関連情報