テキスト処理 - 別のディレクトリの重複ファイル名を使用して検索結果を一意にソートする方法は?

テキスト処理 - 別のディレクトリの重複ファイル名を使用して検索結果を一意にソートする方法は?

どのディレクトリにも重複したファイル名がないように、findコマンドの出力を一意にソートしたいと思います。

find /path/to/first_directory/* /path/to/second_directory/* /path/to/third_directory/* -mtime -1 -name "filename_pattern*"

出力例:

/path/to/first_directory/sample_file1_2017Dec25.dat
/path/to/first_directory/sample_file2_2017Nov01.dat
/path/to/first_directory/sample_file3_2017Oct08.dat
/path/to/first_directory/archive/sample_file1_2017Dec25.dat.Z
/path/to/first_directory/archive/sample_file2_2017Nov01.dat.Z
/path/to/second_directory/sample_file4_2017Sep11.dat
/path/to/second_directory/sample_file5_2017Oct05.dat
/path/to/third_directory/sample_file1_2017Dec25.dat
/path/to/third_directory/sample_file2_2017Nov01.dat
/path/to/third_directory/sample_file3_2017Oct08.dat
/path/to/third_directory/sample_file4_2017Sep11.dat
/path/to/third_directory/sample_file5_2017Oct05.dat
/path/to/third_directory/sample_file6_2017July04.dat
/path/to/third_directory/sample_file6_2017June12.dat
/path/to/third_directory/sample_file7_2017May01.dat

出力では、/first_directory/とに重複したファイル名があり、/first_directory/archive/そのすべてのファイルもその中に/first_directory/*あることがわかります。これは、このディレクトリが で見つかったすべてのファイルのアーカイブディレクトリであることを意味しますが(チェックサム)でしか見つからないファイルもあることを意味します。/second_directory/*/third_directory/*/third_directory/*/first_directory/*/second_directory/*/third_directory/*sample_file6sample_file7

私が印刷したいのは、ファイルをこの順序で/first_directory/、重複せずに日付別に並べ替えるだけです。/first_directory/archive//second_directory//third_directory/

希望の出力:

/path/to/first_directory/sample_file1_2017Dec25.dat
/path/to/first_directory/sample_file2_2017Nov01.dat
/path/to/first_directory/sample_file3_2017Oct08.dat
/path/to/second_directory/sample_file4_2017Sep11.dat
/path/to/second_directory/sample_file5_2017Oct05.dat
/path/to/third_directory/sample_file6_2017July04.dat
/path/to/third_directory/sample_file6_2017June12.dat
/path/to/third_directory/sample_file7_2017May01.dat

ベストアンサー1

find コマンドの出力が名前のファイルに保存されている場合は、filelist次のようにします。

$ awk -F/ '{f=$NF; sub(/\.Z$/,"",f)} !a[f]++' filelist
/path/to/first_directory/sample_file1_2017Dec25.dat
/path/to/first_directory/sample_file2_2017Nov01.dat
/path/to/first_directory/sample_file3_2017Oct08.dat
/path/to/second_directory/sample_file4_2017Sep11.dat
/path/to/second_directory/sample_file5_2017Oct05.dat
/path/to/third_directory/sample_file6_2017July04.dat
/path/to/third_directory/sample_file6_2017June12.dat
/path/to/third_directory/sample_file7_2017May01.dat

ファイルを生成せずに同じことを行うには、次のようにします。

find /path/to/first_directory/* /path/to/second_directory/* /path/to/third_directory/* -mtime -1 -name "filename_pattern*" | awk -F/ '{f=$NF; sub(/\.Z$/,"",f)} !a[f]++'

または、コマンドを複数行に分散させるには、次のようにします。

find /path/to/first_directory/* /path/to/second_directory/* \
  /path/to/third_directory/* -mtime -1 -name "filename_pattern*" |
    awk -F/ '{f=$NF; sub(/\.Z$/,"",f)} !a[f]++'

\bashの行は連続する文字なので、最初の行の末尾に追加します。 2行目はで終わるため、|行連続文字は必要ありません。

どのように動作しますか?

findまず、コマンドのディレクトリを優先順位に従ってリストすることが重要です。私はあなたがこれをしたことを見ます。

  1. -F/

    これは awk に/フィールド区切り文字として使用するように指示します。これはファイル名が最後のフィールドになることを意味します$NF

  2. f=$NF; sub(/\.Z$/,"",f)

    これにより、変数にファイル名が割り当てられ、f最終ファイル名がある場合は削除さ.Zれますf

  3. !a[f]++'

    f以前に見たことがない場合は、この行を印刷してください。

アップデート1:他の拡張機能を削除する

コメントによると、.Zこの拡張機能は削除する必要がある唯一の拡張機能ではありません。他の拡張子がある可能性があり、.dat.ediこの場合は.dat.bak単に 。.dat

awk -F/ '{f=$NF; sub(/\.dat.*/,".dat",f)} !a[f]++' filelist

アップデート2:タイムスタンプでソートされたファイルを表示する:

awk -F/ '{f=$NF; sub(/\.dat.*/,".dat",f)} !a[f]++' filelist | xargs -d'\n' -r ls -t

おすすめ記事