大きなファイルテキスト(ほぼ3 GB)があります-これはログファイルです。このファイルから、7月13日から7月19日までの日付範囲に対応するテキスト行を取得したい。私のログ形式は次のとおりです。
2016-07-12 < ?xml version>
2016-07-13 < ?xml version>
2016-07-18 < ?xml version>
2016-07-18 < ?xml version>
2016-07-19 < ?xml version>
2016-07-20 < ?xml version>
sample text sample text
sample text sample text
sample text sample text
2016-07-20 < ?xml version>
sample text sample text
2016-07-20 < ?xml version>
grep
/sed
の後、次のように出力されます。
2016-07-13 < ?xml version>
2016-07-18 < ?xml version>
2016-07-18 < ?xml version>
2016-07-19 < ?xml version>
どうすれば入手できますか?
grep
を使用すると、必要な行数がわかっている場合は、コンテキストオプション-A
を使用して、パターンの後の行を印刷できます。
grep -A 3 2016-07-13 file
2013-07-13の行と次の3行が表示されます
sed
を使用すると、日付を使用してこのように区切ることができます
sed -n '/2016-07-13/,/2016-07-19/p' file
2016-07-13の最初の行から2016-07-19の最初の行までのすべての行を印刷します。ただし、2016-07-19では1行しかないことを前提としています(次の行は印刷されません)。複数の行がある場合は、代わりに次の日付を使用し、d
を使用して出力を削除します
sed -n '/2016-07-13/,/2016-07-20/{/2016-07-20/d; p}' file
この単純なgrep one linerで十分です:
grep -E ^2016-07-1[3-9] filename
ここではうまく機能し、sedは必要ありません:)
参照:
awk
ソリューション:
$ awk '/^2016-07-13.*/,/2016-07-19.*/' input.txt
2016-07-13 < ?xml version>
2016-07-18 < ?xml version>
2016-07-18 < ?xml version>
2016-07-19 < ?xml version>
基本的に、2016-07-13
で始まる行から2016-07-19
で始まる行までのすべての行を出力します
他のすべての現在の回答は、ログファイルエントリが時系列でソートされているという事実、または日付範囲を正規表現と簡単に一致させることができるという事実に依存しています。より一般的なソリューションが必要な場合は、さらにプログラミングを行う必要があります。
このGNU AWKスクリプトを紹介します。
#!/usr/bin/gawk -f
BEGIN {
starttime = mktime(starttime)
endtime = mktime(endtime)
}
func in_range(n, start, end) {
return start <= n && n < end
}
match($0, /^([0-9]{4})-([0-9]{2})-([0-9]{2})\s/, m) &&
in_range(mktime(m[1] " " m[2] " " m[3] " 00 00 00"), starttime, endtime)
開始時間と終了時間は、変数starttime
およびendtime
を使用して、 mktime
が理解できる形式(YYYY MM DD hh dd ss
)で指定します。したがって、上記のAwkスクリプトが現在の作業ディレクトリの実行可能ファイルfilter-log-dates.awk
にあり、ログファイルがmylog.txt
であると仮定して、awk
コマンドを次のように実行します。
./filter-log-dates.awk -v starttime='2016 07 13 00 00 00' -v endtime='2016 07 20 00 00 00' mylog.txt
終了時間はexclusive、iです。 e。有効なログレコードにはタイムスタンプが必要ですbefore終了時刻。
タイムスタンプの形式が異なる場合は、match
関数に渡される正規表現を調整して調整できます。
手順を踏んで行うことができます。開始パターンに一致する最初の行の番号を見つけます。終了パターンに一致する最後の行の番号を見つけます。次に、これらの2行の間のテストを抽出します。これは次のように実行できます。
grep -n 2016-07-13 bigtextfile | head -1
grep -n 2016-07-19 bigtestfile | tail -1
# Say the first number is 1234 and the second 5678, then use...
awk 'NR>=1234 && NR<=5678' bigtestfile > rangeoftext
これはすべてawk
コマンドで実行できますが、手順を実行することで簡単に実行できる場合があります。 awk内のNR変数は現在の行番号であり、パターン(NR> = 1234 && NR <= 5678)の後にアクションが指定されていないため、デフォルトのアクションはその範囲の行を印刷することです。