8 Gbのログファイル(Railsの運用ログ)があります。いくつかの日付(行)の間にカットする必要があります。これを行うにはどのコマンドを使用できますか?
sed
簡単に実行できます。
8 Gbのログファイル(Railsの運用ログ)があります。いくつかの日付(行)の間にカットする必要があります。これを行うにはどのコマンドを使用できますか?
sed
簡単に実行できます。
回答:
何かのようなもの
sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less
tee cut-log
ファイルに何を入れているかを画面で見ることができますcut-log
。
編集:
fred.bearの厳格な基準を満たすために、sedソリューションがあります(おそらくawkソリューションはかなりきれいです)。
b=BB; e=EE ;echo -e "AA\nAA\nBB\nBB\nCC\nCC\nDD\nDD\nEE\nEE\nFF\nFF" | sed -n ":b;/$b/b p;n;b b;:p;p;n;/$e/b e;b p;:e;p;n;/$e/b e;q"
sed
匹敵することを知るawk
ために、それは実際には少し速かった。
FOOからBARまでのすべてを含めて印刷するには、次を試してください。
$ sed -n '/FOO/,/BAR/p' file.txt
これにより、必要な処理が行わ
れます。パラメータの日付を含めることと除外することの両方が表示されます。
# set Test args
set 2011-02-24 2011-02-26 "junk"
from="$1"
till="$2"
file="$3"
# EITHER ==== +++++++++
# Ouptut lines between two parameter dates INCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 >= from) && ($2 <= till) { print $0 ; next }
($2 > till) { exit }' "$file"
# OR ======== ---------
# Ouptut lines between two parameter dates EXCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 > from) && ($2 < till) { print $0 ; next }
($2 >= till) { exit }' "$file"
フィールド2の(ソートされた)日付をテストします...テストデータの例を次に示します
98 2011-02-05 xxxx
99 2011-02-05 xxxx
100 2011-02-06 xxxx
101 2011-02-06 xxxx
そして、これがtest-data generatorです。
awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
if
ステートメントの持続時間です(1行あたり1でもない)。ロジックフローは事実上同じで、実行時間の差はナノ秒単位でカウントされます。「else」を使用しなかった唯一の理由は、これが事実上私の初めてのスクリプト(1日4年を除く)前、私は)いくつかの例と共演...それが述べたように、私は...見つかった(と最初の実行可能な分岐メカニズムであるとき、それは)同じように高速です..私generly使用。トライawk
sed
q
ログファイルにこの形式の日付がある場合、YYYY-MM-DD
たとえば2011-02-10のすべてのエントリを見つけるには、次のようにします。
grep 2011-02-10 log_file
ここで、2011-02-10と2011-02-11のエントリを検索する場合、もう一度使用しますgrep
が、複数のパターンを使用します。
grep -E '2011-02-10|2011-02-11' log_file
grep
日付範囲がファイルの先頭にある場合でも、ファイル全体を検索します。これは、「範囲内の最後のアイテムの終了」と比較すると、平均して検索時間を2倍にします。質問で言及されている8 GBのファイルサイズのため、 grep時間の結果は、ここのsedの例とほぼ同じです(1分58秒)。タイムテストの結果へのリンクを次に示します。paste.ubuntu.com
このサイズのファイルでの作業は常に困難です。
次の方法は、このファイルをいくつかの小さなファイルに分割することです。これを行うには、splitコマンドを使用します。
split -d -l 50000 ToBigFile.data file_
分割されても、bash forループを使用する場合のようにファイルを操作できます。
for f in `ls file_*`; do cat $f; done;
しかし、猫の代わりに、逆grepを使用して不要なデータを取り除くことができます。これはこれには関係ありません。(または必要な改良の種類)。
この時点で、多くの小さなファイルを操作するだけで、他の上記のコマンドは、多くの小さなファイルを処理します。
そして、完了したら、2番目のforループを使用して、新しい小さなファイルを再度作成します。
for f in `ls file_*`; do cat $f >> NewFile.data ; done;
更新 データを複数のファイルに分割し始めるため、ハードドライブで多くの作業が必要になり、時間がかかります。(この質問ではどうやら5分)。
一方、次の手順はおそらくより高速です。
したがって、この方法は単純なgrep、awk、sed操作にはおそらく意味がありませんが、検索パターンがより複雑になると、より高速になる可能性があります。
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file