レコード内の日付/時刻位置が異なる可能性があるレコードの日付/時刻部分に基づいてリストをソートします。

レコード内の日付/時刻位置が異なる可能性があるレコードの日付/時刻部分に基づいてリストをソートします。

名前の日付/時刻部分に基づいてリストをソートしたいと思います。

ソートを使用できますか?以下の入力例のように列が異なる可能性があるため、ソート列を指定することはできません。

swid_ds_install_user_20171227172654_20425.log
package_user_20171227172949_5627.log
swid_state_definition_user_20171227162839_6515.log
swid_ds_install_user_20171227172732_23839.log
swid_appsrv_stop_user_20171227172258_27116.log
package_user_20171227172610_16198.log
swid_state_definition_user_20171227172344_322.log
package_user_20171227233634_23845.log
package_user_20171227162858_7082.log

たとえば、フィールドの順序を変更できます。

awk -F_ '{for (i=NF;i>0;i--){printf $i"_"};printf "\n"}'

次に -d_ -k2,2 でソートし、元のファイル名を保持するためにフィールドの順序を逆にします。たとえば、sed を使用して残りの区切り文字を削除します。しかし、これは厄介です。

awk -F_ '{for (i=NF;i>0;i--){printf $i"_"};printf "\n"}' | sort -t'_' -k2,2 \
| awk -F_ '{for (i=NF;i>0;i--){printf $i"_"};printf "\n"}' | sed 's/^_//' \ 
| sed 's/_$//'

この問題をどのように処理しますか?

sedを使用して正規表現を介して日付/時刻部分を分離してソートし、出力を印刷するときに一致する正規表現だけでなく、完全なファイル名を回復するためにいくつかの組み込み機能を使用するつもりです。

別のレプリカを作成していないことを願っています。問題の説明を実際に要約することはできません。

ベストアンサー1

awk -F_ '{print $(NF-1), $0}' | sort -k1,1 -n | cut -d' ' -f2-

これは、フィールド区切り文字としてawkwithを使用して_2番目のフィールドを最後のフィールド(日時)を行の先頭に追加し、sortそのフィールドの入力のみを数値でソートしてから、追加フィールドを削除するcutために使用されます。

サンプル出力は、サンプル入力を次の名前のファイルに保存しますfile

$ awk -F_ '{print $(NF-1), $0}' file  | sort -k1,1 -n | cut -d' ' -f2-
swid_state_definition_user_20171227162839_6515.log
package_user_20171227162858_7082.log
swid_appsrv_stop_user_20171227172258_27116.log
swid_state_definition_user_20171227172344_322.log
package_user_20171227172610_16198.log
swid_ds_install_user_20171227172654_20425.log
swid_ds_install_user_20171227172732_23839.log
package_user_20171227172949_5627.log
package_user_20171227233634_23845.log

これは、日付/時刻が常に2番目から最後のフィールドにあると仮定します。もしそうならいいえこの場合、GNU awkを使用すると、次のパターンをキャプチャできます。そうだ日付/時刻のように行の先頭に追加します。

$ awk -F_ '{match($0,"_(20[0-9]{12})_",dt); print dt[1], $0}' file |
    sort -k1,1 -n | cut -d' ' -f2-

しかし、私はperlこのような場合に使用する方です。

GNU awkのmatch()関数は、オプションの3番目の引数、つまりキャプチャされた一致を格納するために使用される配列変数の名前を使用します。この場合、キャプチャは1つしかないため、配列の最初の要素に保存されます(例:)dt[1]。 IIRC、POSIX awkにはまだ正規表現一致をキャッチする方法はありません。

ところで、今の仮定は年>= 2000です。入力データが常にそうでない場合は、正規表現を適切に調整してください。

おすすめ記事