2

私は現在、いくつかのログ ファイルをサニタイズして読みやすい形式にしようとしており、かなりうまく機能する gnu cut コマンドを使用しようとしていますが、[INFO] を削除する良い方法は本当に思いつきません。文字列の一部

logs/logs/server_1283258036.log:2010-08-31 23:06:51 [INFO] <NateMar> where?!
logs/logs/server_1281904775.log:2010-08-15 22:59:53 [INFO] <BoonTheMoon> §b<BoonTheMoon>§ohhhhhh
logs/logs/server_1282136782.log:2010-08-18 16:27:32 [INFO] <pinguin> <pinguin>§F :/
logs/logs/server_1282136782.log:2010-08-18 16:27:37 [INFO] <TotempaaltJ> <TotempaaltJ>§F That helped A LOT
logs/logs/server_1282136782.log:2010-08-18 16:27:37 [INFO] <Rizual> §b<Rizual>§F hm?
logs/logs/server_1282136782.log:2010-08-18 16:29:10 [INFO] <pinguin> <pinguin>§F bah
logs/logs/server_1282136782.log:2010-08-18 16:29:35 [INFO] <TotempaaltJ> <TotempaaltJ>§F Finished my houses 
logs/logs/server_1282136782.log:2010-08-18 16:29:40 [INFO] <TotempaaltJ> <TotempaaltJ>§F or whatever
logs/logs/server_1282136782.log:2010-08-18 16:30:47 [INFO] <Rizual> §b<Rizual>§So much iron
logs/logs/server_1282136782.log:2010-08-18 16:30:58 [INFO] <TotempaaltJ> <TotempaaltJ>§F Ah yes, furnaces don't work.o
logs/logs/server_1282136782.log:2010-08-18 16:31:01 [INFO] <Rizual> §b<Rizual>§F They do
logs/logs/server_1282136782.log:2010-08-18 16:31:06 [INFO] <TotempaaltJ> <TotempaaltJ>§F Hm
logs/logs/server_1282136782.log:2010-08-18 16:31:08 [INFO] <Rizual> §b<Rizual>§F just need to use /lighter
logs/logs/server_1282136782.log:2010-08-18 16:31:12 [INFO] <Valrix> <Valrix>§FNotch fixed them?

最終的には、文字列を次のようなものにまとめたいと思います (上記のログの大部分に見られるように、ログは 2 つの形式であり、名前のコピーが 2 つある古い形式であることに注意してください。また、名前が一度だけ含まれる新しい形式もあります(最初のログ行で確認できます<natemar>))

2010-08-31 23:06:51 <NateMar> where?!    
2010-08-15 22:59:53 <BoonTheMoon> ohhhhhh (this one would require both the same editing as above, plus removal of the "extra" name §b<BoonTheMoon>§)    

これを行うにはどうすればよいですか?awk を使用することを考えましたが、それがどのように機能するかを把握するのに苦労しているため、それを行うための設定方法がわかりません。どんな助けでも大歓迎です、ありがとう!

4

4 に答える 4

3

コマンドを使用して、正しい方向に進んでいますcut。[INFO]フィールドを削除するための鍵は、最終出力からそれを除外することです。-f1,2,4-引数は、その時点で[INFO]である3番目を除くすべてのフィールドを含めることによって、まさにそれを行い ます

cut -d: -f2- Input.txt | cut -d' ' -f1,2,4- > Output.txt    
于 2012-09-10T00:33:50.857 に答える
3

sed、awk、およびbashで、これをさらに実行します。

[ghoti@pc ~]$ cat text
logs/logs/server_1283258036.log:2010-08-31 23:06:51 [INFO] <NateMar> where?!
logs/logs/server_1281904775.log:2010-08-15 22:59:53 [INFO] <BoonTheMoon> §b<BoonTheMoon>§ohhhhhh

[ghoti@pc ~]$ sed 's/^[^:]*://;s/[[][^]]*[]] //' text
2010-08-31 23:06:51 <NateMar> where?!
2010-08-15 22:59:53 <BoonTheMoon> §b<BoonTheMoon>§ohhhhhh

[ghoti@pc ~]$ awk '{sub(/^[^:]+:/,""); $3=""} 1' text
2010-08-31 23:06:51  <NateMar> where?!
2010-08-15 22:59:53  <BoonTheMoon> §b<BoonTheMoon>§ohhhhhh

[ghoti@pc ~]$ while read line; do line=${line#*:}; echo "${line/\[*\] }"; done < text
2010-08-31 23:06:51 <NateMar> where?!
2010-08-15 22:59:53 <BoonTheMoon> §b<BoonTheMoon>§ohhhhhh

これらは単純ですが、短さのために不完全な場合があります。たとえば、awk スクリプトは、3 番目の「単語」を削除することで、null になった単語を区切るスペースを残します。

ワンライナーは迅速な仕事のために「エレガント」に見えるかもしれませんが、特に未知の入力データを処理する必要がある場合や、直後に結果を検査しない場合は、コードを明示することをお勧めします。あなたは物事を実行します。

これは読みにくいですが、入力によってははるかに安全になる可能性があります。

[ghoti@pc ~]$ awk '$3~/^[[].+[]]$/{$3="";sub(/  /," ")} {sub(/^[^:]+:/,"")} 1' text
2010-08-31 23:06:51 <NateMar> where?!
2010-08-15 22:59:53 <BoonTheMoon> çb<BoonTheMoon>çohhhhhh

bash スクリプトの場合、glob ではなく文字クラスを使用する方が安全です。

[ghoti@pc ~]$ shopt -s extglob
[ghoti@pc ~]$ while read line; do line=${line#*:}; echo "${line/\[+([[:upper:]])\] /}"; done < text
2010-08-31 23:06:51 <NateMar> where?!
2010-08-15 22:59:53 <BoonTheMoon> çb<BoonTheMoon>çohhhhhh

extglobshopt オプションを使用すると、パラメーター置換パターン内でより高度なパターン マッチングを使用できること に注意してください。man bash詳細を探しますPathname Expansion

アップデート:

当初はなかった新しい要件を質問に追加しました。awk を使用して新しい要件を達成する方法は次のとおりです。

awk '$3~/^[[].+[]]$/{$3="";sub(/  /," ")} {sub(/^[^:]+:/,"")} $3~/^<.+>$/{sub(/^(§b)?<[[:alpha:]]+>§/,"",$4)} 1' text

これにより、3 番目の文字列が括弧で囲まれたニックネームのように見える場合、4 番目の文字列から色付きのニックネームが削除されます。これは投稿したサンプルで機能しますが、これが機能するかどうかを判断できるのはあなただけです。

そしてバッシュで:

shopt -s extglob
while read date time tag nick line; do
  printf "%s %s %s %s\n" "${date#*:}" "$time" "$nick" "${line/#*([^< ])$nick??}"
done < text
于 2012-09-10T01:41:22.550 に答える
2

(上記のコメントに投稿された質問への回答に基づいて、保留中の改訂の可能性があります)

使用awk:

awk '{sub(".log:", ".log "); print $2, $3, $5, $6}' data.txt

あなたに与える:

2010-08-31 23:06:51 <NateMar> where?!
2010-08-15 22:59:53 <BoonTheMoon> §b<BoonTheMoon>§ohhhhhh

説明:

:" " の後ろを空白に変更する.log:と、行内のフィールドを空白で区切ることができました。あなたが興味を持っていたフィールドは 2、3、5、6 だったので、行の各フィールドの内容を取得するためにawkを使用して出力しました。$

printf必要に応じて、 を使用してデータをより正確にフォーマットすることもできます。

于 2012-09-09T21:36:17.207 に答える
1

それを使用sedすると、よりデモスト的に実行できます。

$> cat ./text
logs/logs/server_1283258036.log:2010-08-31 23:06:51 [INFO] <NateMar> where?!
logs/logs/server_1281904775.log:2010-08-15 22:59:53 [INFO] <BoonTheMoon> §b<BoonTheMoon>§ohhhhhh

$> sed -r -e 's/^.*log:([0-9]{4}-[0-9]{2}-[0-9]{2}\ )([0-9\ \:]*\ )(\[[A-Z]*\]\ )(.*)$/\1\2\4/' ./text
2010-08-31 23:06:51 <NateMar> where?!
2010-08-15 22:59:53 <BoonTheMoon> §b<BoonTheMoon>§ohhhhhh

全体的なアイデアは、ログ文字列のいくつかのフィールドを一致させてから、必要なものだけを残すことです。

于 2012-09-09T21:55:52.907 に答える