
次のログファイルがあります。
2016-05-31 09:54:36 (16667) heritage_w?
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?i=290
#accesses 3,435 (#welcome 415) since 03/07/2012
2016-05-31 09:54:41 (16677) heritage_w?w=
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?
#accesses 3,436 (#welcome 416) since 03/07/2012
2016-06-01 04:07:06 (22190) heritage_w?m=MOD_IND;i=88
From: ubunzeus
User: user2 (wizard)
Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?i=88
#accesses 3,623 (#welcome 441) since 03/07/2012
2016-06-01 04:07:38 (22255) heritage_w?m=MOD_FAM;i=28;ip=88
From: ubunzeus
User: user2 (wizard)
Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?m=MOD_IND;i=88
#accesses 3,624 (#welcome 441) since 03/07/2012
私はレコード区切り記号で歪みのない行を取得しようとしていますRS
。
次のようなコードを使用します。
$ gawk 'BEGIN{RS="^2016"}; /user1/ {print}'
「user1」を含むレコードだけを印刷したいです。
現在、コマンドラインはファイル全体...すべてのレコードを印刷しています。
予想される結果は次のとおりです。
2016-05-31 09:54:36 (16667) heritage_w?
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?i=290
#accesses 3,435 (#welcome 415) since 03/07/2012
2016-05-31 09:54:41 (16677) heritage_w?w=
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?
#accesses 3,436 (#welcome 416) since 03/07/2012
この問題の具体的な内容を明確にしてください。
私は答えを受け入れた。ジョン1024これにより、私に必要な記録を選択できます。しかし、誰かが特定の正規表現関数をレコード区切り文字(RS)変数として使用する方法を最終的に理解できることを願っています。この場合、インデントされていない行になります。
John1024の説明に従って、使用中の文字列を取得し、白ではなく正規表現をさまざまな組み合わせで使用しましたが、機能しません。
レコードを正しくフィルタリングしない私が使用する行は次のとおりです。
$ gawk 'BEGIN{RS='\n\S'}; /user1/ {print}' event.log
$ gawk 'BEGIN{RS='\S'}; /user1/ {print}' event.log
$ gawk 'BEGIN{RS="\n^\S"}; /user1/ {print}' event.log
$ gawk 'BEGIN{RS="^\S"}; /user1/ {print}' event.log
上記のすべての組み合わせはすべての履歴を表示します。一重引用符は、'^\S'
エスケープされた意味ではなく実際の文字を使用していると確信しています。二重引用符に"^\S"
エラーメッセージが表示されました。
gawk: cmd. line:1: warning: escape sequence `\S' treated as plain `S'
「\S」正規表現が白ではなく最初の列文字であることを確認できました。オンラインでインデントされていない行を表示します。
$ egrep "^\S" event.log
上記のcliの出力:
2016-05-31 09:54:36 (16667) heritage_w?
2016-05-31 09:54:41 (16677) heritage_w?w=
2016-06-01 04:07:06 (22190) heritage_w?m=MOD_IND;i=88
2016-06-01 04:07:38 (22255) heritage_w?m=MOD_FAM;i=28;ip=88
許可された回答の助けを借りて...コードをラップし、二重バックスラッシュを使用してエスケープ文字エラーを解決すると、次は必須レコードをフィルタリングします。
$ gawk 'BEGIN{RS="\n\\S"}; /user1/ {print}' event.log
答え1
努力する:
$ gawk 'BEGIN{RS="\n2016"}; /user1/ {print}' input
これにより出力が生成されます。
2016-05-31 09:54:36 (16667) heritage_w?
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?i=290
#accesses 3,435 (#welcome 415) since 03/07/2012
-05-31 09:54:41 (16677) heritage_w?w=
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?
#accesses 3,436 (#welcome 416) since 03/07/2012
2番目のレコードにはソースがありません2016
。それは。もちろん、それが2016
レコード区切り文字の一部になるからです。記録処理を開始する前にこのセクションを復元するには、次のようにします。
gawk 'BEGIN{RS="\n2016"} NR>1{$0="2016" $0;} /user1/ {print}' input
改善する
このバージョンでは、必要に応じて各行の先頭にテキストを復元します。
gawk '{$0=substr(last,2)$0;} /user1/{print} {last=RT}' RS='\n[^[:space:]]' input
仕組み:
{$0=substr(last,2)$0;}
$0
レコード区切り文字で削除されたテキストの前に追加されます。substr
前の改行文字を削除するために使用されます。/user1/{print}
興味のあるレコードを印刷してください。{last=RT}
実際のレコード区切り文字を保存して、その一部が次のレコードの前に追加されるようにします。RT
これはGNU拡張であり、他のバージョンのawkではサポートされていません。RS='\n[^[:space:]]'
レコード区切り文字を改行文字に設定し、その後に空白以外の文字が続きます。正規表現をレコード区切り文字として使用することは、GNU awkで機能します。
例:
$ gawk '{$0=substr(last,2)$0;} /user1/{print} {last=RT}' RS='\n[^[:space:]]' input
2016-05-31 09:54:36 (16667) heritage_w?
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?i=290
#accesses 3,435 (#welcome 415) since 03/07/2012
2016-05-31 09:54:41 (16677) heritage_w?w=
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?
#accesses 3,436 (#welcome 416) since 03/07/2012
答え2
これは少し異なる戦略です。インデントされた各行を格納バッファに蓄積します。インデントされていない行を読み取ると、バッファを印刷し(必要なパターンが含まれている場合)、バッファの内容を新しいヘッダー行に置き換える関数を呼び出します。また、ファイルの終わりに達したときにこの関数を呼び出す必要があります。
#!/usr/bin/awk -f
# Select records from a file
# Each record header line is unindented and each record body line is indented
# Written by PM 2Ring 2015.06.02
function ShowSelected()
{
if (hold ~ /User: user1/)
printf "%s", hold
hold = $0 ORS
}
/^ /{hold = hold $0 ORS; next}
{ShowSelected()}
END{ShowSelected()}
以下は一行バージョンです。
awk 'function S(){if(h~/User: user1/)printf "%s",h; h=$0 ORS}; /^ /{h=h $0 ORS; next}; {S()};END{S()}'
ここで楽しいSedバージョンがあります。本質的に同じアルゴリズムを使用します。
sed '/^ /!bA;H;$bA;d;:A;x;/User: user1/!d'
コメントも同じです。
#!/bin/sed -f
# Select records from a file
# Each record header line is unindented and each record body line is indented
# Written by PM 2Ring 2015.06.02
# If line doesn't start with a space, branch to the select & display routine
/^ /!bA
# Append pattern space (i.e., the current line) to the hold space
H
# If this is the last line, branch to the select & display routine
$bA
# Delete the pattern space and start the next cycle
d
# The select & display routine
:A
# Exchange the contents of the hold and pattern spaces
x
# Delete the pattern if it doesn't contain the regex /User: user1/
# if the pattern isn't deleted it will be printed
/User: user1/!d
これは、sedを使用していくつかの前処理を実行したいThorのアイデアに触発されたsed-awkハイブリッドです。インデントされていない各行の前に\xff
文字を付け、それをawkレコード区切り文字として使用します。ログファイル\xff
自体がその文字を使用している場合は機能しませんが、そうでないことを願っています。 :)
<logfile sed 's/^[^ ]/\xff&/' | awk 'BEGIN{RS="\xff";ORS=""};/User: user1/'
答え3
sed
たとえば、ファイルを前処理します。したがって、各レコードの2行目を抽出するには、次のようにします。
<infile sed 's/^[^ ]/&\n/' | awk '{ print $2 }' RS= FS='\n'
出力:
From: ip68-8-49-100.sd.sd.cox.net
From: ip68-8-49-100.sd.sd.cox.net
From: ubunzeus
From: ubunzeus
編集 - 以下を含む$3
すべての履歴をどのように印刷できますかuser1
?
<infile sed '1!s/^[^ ]/\n&/' | awk '$3 ~ /user1/' RS= FS='\n'
出力:
2016-05-31 09:54:36 (16667) heritage_w?
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?i=290
#accesses 3,435 (#welcome 415) since 03/07/2012
2016-05-31 09:54:41 (16677) heritage_w?w=
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?
#accesses 3,436 (#welcome 416) since 03/07/2012
答え4
IMOの最も簡単な方法は、sed
入力を段落区切りレコード(各レコード間に1つ以上の空行)に変換することです。つまり、最初の行をスキップし、空白(スペースまたはタブ)で始まらない各行の前に改行文字を挿入します。
awk
その後、複数の改行を入力レコード区切り記号(RS)として使用するように指示できますRS='\n\n+'
。
ただし、出力を段落に含める必要がない限り、出力レコード区切り文字(ORS)を同じにする必要はありません。これを要請しなかったので含めなかった。これが必要な場合(たとえば、出力に対して追加の処理を実行したい場合など)、オプション-v ORS='\n\n'
に追加します。awk
$ sed -e '2,$ s/^[^[:blank:]]/\n&/' ldjames.txt |
awk -v RS='\n\n+' '/user1/ {print}'
2016-05-31 09:54:36 (16667) heritage_w?
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?i=290
#accesses 3,435 (#welcome 415) since 03/07/2012
2016-05-31 09:54:41 (16677) heritage_w?w=
From: ip68-8-49-100.sd.sd.cox.net
User: user1wizard (wizard)
Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Referer: http://dbase.apollo3.com/heritage_w?
#accesses 3,436 (#welcome 416) since 03/07/2012