シェルスクリプトを使用して、一意のファイル名形式と最新の作成日を持つ特定のPDFを選択しますか?

シェルスクリプトを使用して、一意のファイル名形式と最新の作成日を持つ特定のPDFを選択しますか?

スクリプトの助けが必要です。現在のファイル名の特定の要件を満たすPDFファイルを選択して別の場所に移動しようとしています。

私が選択したいファイル名の形式には、以下の例に示すように別々のセクションがあります。

I_XXX_PACK_6788669_6_9358869.pdf

私が望むのは、ファイル名の最後の部分(たとえば9358869)を持つファイルのみを選択し、ディレクトリ内の他のすべてのpdfファイルを無視することです。

Unixツール(POSIX find、sed、grepなど)を使用して実行できますか?私の主な問題は、ファイル名の6つの区切られた部分で構成される1つのファイルのみをインポートし、他のすべてのファイルは無視しようとしていることです。

  • そして、システム時間の1時間前に生成されたファイルだけを選択できますか?時間を確認するために、他のファイル形式ではsedを使用しましたが、pdfファイルでは使用しませんでした。だからこれが可能かどうかはわかりません。

答え1

のようなファイルがあり、6つの区切られたセクションに一致するファイルのみがI_XXX_PACK_6788669_6_9358869.pdf必要です_9358869

これは、次に終わる(ゼロ文字以上のワイルドカード)で区切られた少なくとも6つの_部分と一致します。*_9358869.pdf

*_*_*_*_*_9358869.pdf

以下を使用して、過去1時間に変更されたが生成されなかったファイルを見つけることができますfind

find /path/to/directory -type f -mmin -60

POSIXを許可するには、適切な年齢を使用して-newer {file}設定する必要があります。{file}POSIXは、ファイルの変更日時を過去1時間に設定する安定した方法を提供していませんが、表示されているように私達はそれを使用できます:

printf -v curr '%(%s)T'
past=$(printf '%(%Y%m%d%H%M)T\n' "$((curr - 60*60))")
touch -t "$past" /path/to/timestamp

find /path/to/directory -type f -newer /path/to/timestamp

最後に、2つをマージします。

touch -t "$(printf -v curr '%(%s)T'; printf '%(%Y%m%d%H%M)T\n' "$((curr - 60*60))")" /path/to/timestamp
find /path/to/directory -type f -newer /path/to/timestamp -name '*_*_*_*_*_9358869.pdf'

答え2

find . -name '[!_]*_*_*_*_*_*[!_].pdf' ! -name '*_*_*_*_*_*_*' ! -name '*__*'

.pdf名前が5〜5文字で終わり、ルート名の__区切り部分が空でないファイル(すべてのタイプ)が報告されます。

一部のfind実装では、現在のロケールで名前をテキストにデコードできないファイルも除外されます。

Chrisが言ったように、過去の時間に修正された内容を制限するために、いくつかの実装はそれをサポートするか標準-newermt '1 hour ago'ではなく、それ以外はPOSIXと同等のものはありません。-mmin 60-mtime -1mfind-newer some-file-with-a-last-modification-time-one-hour-ago

POSIX 方式で検索基準時間を生成する一般的な方法は次のとおりです。

TZ=XXX0 touch -t "$(TZ=XXX1 date +%Y%m%d%H%M.%S)" some-file-with-a-last-modification-time-one-hour-ago

ここではタイムゾーン(タイムゾーンと名付けたが、ここでは名前は無関係)で呼び出され、dateUTCより1時間遅く定義し、結果のタイムスタンプをUTC時間(タイムゾーンとも呼ばれますが、UTC 0時間後(UTC)より古いため、最終的に1時間ファイルが生成されます。XXXtouchdateXXX

その後、次のことができます。

find . -name '[!_]*_*_*_*_*_*[!_].pdf' \
       ! -name '*_*_*_*_*_*_*' \
       ! -name '*__*' \
       -newer some-file-with-a-last-modification-time-one-hour-ago

あなたと同じならタグは、POSIX構文の使用に限定されず、外部ユーティリティなしですべての操作を実行できる場所でsh使用できることを示します。zsh

set -o extendedglob
print -rC1 -- **/([^_]##_)(#c5)_[^_]##.pdf(ND-.mh-1)

どこ:

  • **/すべてのレベルのサブディレクトリと一致(0を含む)
  • [^_]以下を除くすべての文字と一致します。_
  • x##と同様に、1つ以上のxesと一致しますx(#c1,)
  • x(#c5)正確に5 xesに一致します。
  • N一致するものがない場合、ullglobはエラーを報告するのではなく空の状態に展開されます。
  • Dotglobには隠しコンテンツが含まれています。
  • .mh-1一般ファイルは最後に変更されてから1時間未満(または今後)で、シンボリック-リンクの確認後にチェックが実行されます。
  • print -rC1 -- print議論はrawとolumnにあります1 C

最後の3つの部分が10進整数でなければならないファイルに一致を制限するには、次のように変更できます。

set -o extendedglob
print -rC1 -- **/([^_]##_)(#c3)<->_<->_<->.pdf(ND-.mh-1)

数値一致演算子の形式はどこに<->ありますが、<1-20>ここには境界がないため、すべての10進整数が一致します(1つ以上のASCII 10進シーケンスを作成することもできます[0-9]##)。


¹-type fタイプのみを考慮したファイルを追加できます。定期的な(fifo、デバイス、ディレクトリ、パイプとは対照的に...)しかし、通常のファイルへのシンボリックリンクも除外されることに注意してください。これを含める必要があります-xtype fが、これは非標準(GNU)拡張でもあります。

関連情報