web-dev-qa-db-ja.com

grep / sort / findを使用して一意の値を抽出する

YYYYMMDD.Txt形式で名前が付けられたテキストファイルがたくさんあります(したがって、今日は20160420.Txtになります)。

各ファイルは基本的にタイムスタンプと一意のIDを含むログであり、各値はタブ区切り文字で区切られます。

したがって、たとえば、20160420.Txtの値は次のとおりです。

DATE        TIME   ID
20160420   0135   123456
20160420   0240   234567
20160420   1252   345678

これらのファイルに存在するすべての一意のIDを抽出する必要がありますが、過去6か月のファイルのみです。

問題は、過去1週間にすべてのファイルが再作成されたため、mtimeを使用できないことです(つまり、mtimeがファイル名に対応していません)。

grep/find/sortでこれを行う方法はありますか?

3
listerblack

6か月前の正確な日付を見つけることは簡単ではありません。特に、現在の日付が特定の月の31日である場合はそうです。しかし、find-mtimeを使用してこれを行う方法を知っている場合は、名前の日付に応じてファイルに触れるだけです。

for x in *.Txt; do
   dd=${x%.Txt}
   touch -t "$dd"0000 "$x"
done

次に、mtimeを使用します

2
Anthon

作業を行うにはawkを使用し、日付にはSQLiteを使用します。

sqlite3 <<< "select date('2016-04-20', '-6 month');"
2015-10-20

ダンディ、そうではありませんか? awkには、SQLiteが必要とするハイフンを挿入/削除する文字列関数があり、タブ区切り文字で分割されます。

awk 'NR == 1 {next}; { IDS[$3]++ }; END {for (K in IDS) {print K}}' ids
123456
345678
234567

速い保証も。

1
James K. Lowden

別の回答に対する@casのコメントのフォローアップ:

six_months=$(date -d "6 months ago" "+%Y%m%d")
for f in *.Txt; do
    file_date=${f%.Txt}
    [[ $file_date > $six_months ]] && echo "$f"
done |
  xargs awk 'FNR > 1 {print $3}' |
  sort -u > unique_ids_in_last_6_months

Forループは、「適格な」ファイル名を出力します。 xargsはファイル名を渡して一度にバッチをawkします(awkへの呼び出しの数を最小限に抑えます)。 awkはヘッダーを破棄し、最後の列を出力します。 sortは、一意のIDを見つけます。

1
glenn jackman