以下のようにタイムスタンプでソートされたファイルのリストを提供します。各ファイルの最後の項目(各ファイルの一番下のファイル)を検索しようとしています。
たとえば、
archive-daily/document-sell-report-2022-07-12-23-21-02.html
archive-daily/document-sell-report-2022-07-13-23-15-34.html
archive-daily/document-loan-report-2022-07-18-05-12-16.html
archive-daily/document-loan-report-2022-07-18-17-07-26.html
archive-daily/document-deb-report-2022-07-18-13-17-40.html
archive-daily/document-deb-report-2022-07-18-10-04-21.html
次のようになります。
archive-daily/document-sell-report-2022-07-13-23-15-34.html
archive-daily/document-loan-report-2022-07-18-17-07-26.html
archive-daily/document-deb-report-2022-07-18-10-04-21.html
これを達成するためにawkまたは他のコマンドを使用できますか?よろしくお願いします。
答え1
$ tac file | awk '!seen[substr($0,1,length()-25)]++'
archive-daily/document-deb-report-2022-07-18-10-04-21.html
archive-daily/document-loan-report-2022-07-18-17-07-26.html
archive-daily/document-sell-report-2022-07-13-23-15-34.html
答え2
使用sed
とtac
$ sed -En 'G;/^(([^-]*-){3}).*\n.*\n\1/d;H;P' <(tac input_file)
archive-daily/document-sell-report-2022-07-13-23-15-34.html
archive-daily/document-loan-report-2022-07-18-17-07-26.html
archive-daily/document-deb-report-2022-07-18-10-04-21.html
答え3
AWKを使用する:プログラムは古いファイルのプレフィックスを保存し、現在のファイルのプレフィックスを取得して比較し、プレフィックスが変更されると古いファイル名を印刷します。
# myuniq.awk
BEGIN {
last_prefix = 0
last_line = 0
}
{
if (match($0, /(-[[:digit:]]+){6}\.html$/) == 0)
next
prefix = substr($0, 1, RSTART - 1)
if (last_prefix != 0 && prefix != last_prefix)
print last_line
last_prefix = prefix
last_line = $0
}
END {
if (last_line != 0)
print last_line
}
$ cat files.txt
archive-daily/document-sell-report-2022-07-12-23-21-02.html
archive-daily/document-sell-report-2022-07-13-23-15-34.html
archive-daily/document-loan-report-2022-07-18-05-12-16.html
archive-daily/document-loan-report-2022-07-18-17-07-26.html
archive-daily/document-deb-report-2022-07-18-13-17-40.html
archive-daily/document-deb-report-2022-07-18-10-04-21.html
$ awk -f myuniq.awk < files.txt
archive-daily/document-sell-report-2022-07-13-23-15-34.html
archive-daily/document-loan-report-2022-07-18-17-07-26.html
archive-daily/document-deb-report-2022-07-18-10-04-21.html
答え4
使用幸せ(以前のPerl_6)
~$ raku -e 'my @a = lines>>.split(/ "/" | [ <?after report> \- ]/); \
my %h.=append: [Z=>] @a>>[1], @a.map(*.[2]); \
for %h.sort {say (.key, .value.max).join("-")};' file.txt
この答えは、質問を少し単純化し、分析する必要があるすべてのファイルが同じディレクトリにあると仮定します。したがって、split
最初のステップはディレクトリを閉じることです。ディレクトリを含めると、コードが正しく実行されることに注意してください(長さが長くなるだけですkey
)。アルファベット「レポート」の順序で返されるサンプル出力:
入力例:
archive-daily/document-sell-report-2022-07-12-23-21-02.html
archive-daily/document-sell-report-2022-07-13-23-15-34.html
archive-daily/document-loan-report-2022-07-18-05-12-16.html
archive-daily/document-loan-report-2022-07-18-17-07-26.html
archive-daily/document-deb-report-2022-07-18-13-17-40.html
archive-daily/document-deb-report-2022-07-18-10-04-21.html
出力例:
document-deb-report-2022-07-18-13-17-40.html
document-loan-report-2022-07-18-17-07-26.html
document-sell-report-2022-07-13-23-15-34.html
最初のステートメントでは、「report」という単語の後のスラッシュまたはハイフンでlines
読み取り、破壊的に分割して配列に保存します。ハッシュを宣言し、ハッシュに3つの要素を追加します。各「Zip-reduction」は対応するデータストアを取り出し、キーと値の関係に「fat-arrow」を追加します。したがって、複合メタ演算子を使用します。したがって、最初の要素は2番目の要素()になります。その後、値を計算して結果を返します。/
-
@a
%h
append
[Z]
=>
[Z=>]
key
value
max
join
これが面白いところです。 RakuにはISO-8601
DateTimesが組み込まれているので、2番目の要素をオブジェクトsubst
として認識するように置き換えることができます。したがって、実際の結果をDateTime
得ることができます。max
DateTime
~$ raku -e 'my @a = lines>>.split(/ "/" | [ <?after report> \- ]/); \
my %h.=append: [Z=>] @a>>[1], @a.map(*.[2].subst(/ \- (\d**2) \- (\d**2) \- (\d**2) \.html $/, {"T$0:$1:$2"} ).DateTime); \
"".put; for %h.sort {say (.key => .value.max)};' file.txt
document-deb-report => 2022-07-18T13:17:40Z
document-loan-report => 2022-07-18T17:07:26Z
document-sell-report => 2022-07-13T23:15:34Z
詳しくは下記をご覧ください。すべてのレポートはmax
日付/時刻を返します。これは単にOPのデータが間違っていることです(@QuartzCristalが指摘したように)。
https://docs.raku.org/言語/hashmap#Mutable_hashes_and_immutable_maps
https://docs.raku.org/言語/operators#index-entry-[]_(reduction_metaoperators)
https://docs.raku.org/type/DateTime
https://raku.org