ログファイルから日付を抽出し、一意の日付を含むファイルを作成する

ログファイルから日付を抽出し、一意の日付を含むファイルを作成する

ファイルから日付形式の日付を抽出したいですDD.MM.YYYY。日付は常に最初の位置にあります。以下は項目の例です。

15.04.2016 13:13:30,228 INFO    [wComService] [mukumukuko@system/3] Call created with id:VoiceConnector$mukumukuko@system$D1:1:0:CB:SESSION$D1:1:0:DB:mukumukuko@system$D1:1:0:HB:_TARGET^M
15.04.2016 13:14:10,886 INFO    [wComService] Call 5303 from device +41999999999^M
15.04.2016 13:14:20,967 INFO    [AddressTranslatorService][mukumukuko@system/3] </convertLocalToGNF>^M
15.04.2016 13:14:20,992 INFO    [wComService] [mukumukuko@system/3] Call created with id: VoiceConnector$mukumukuko@system$D1:1:0:MB:SESSION$D1:1:0:NB:mukumukuko@system$D1:1:0:RB:_TARGET^M
15.04.2016 13:15:18,760 INFO    [OSMCService] SessionManager Thread - Heartbeat (1clients connected)^M

ファイルには1週間のアクティビティログが含まれているため、ファイル内の日付(たとえば、、、など16.04.201617.04.2016も検索できます18.04.2016

このファイルには、Java 例外に対する次の出力も含まれる場合があります。

    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

私は以下を試しました:

cat fac.log | sed 's/^.*\([0-9]\{2\}.[0-9]\{2\}.[0-9]\{4\}\).*$/\1/' > datesF1

しかし、「datesF1」に希望の日付が表示されますが、これらのJava例外メッセージが表示されます。

だから私が望むのは、繰り返しせずに一意の日付のみを表示するファイルを生成することです。たとえば、「datesF1」は次のようになります。

15.04.2016
16.04.2016
17.04.2016
18.04.2016

これが可能かどうか、またはgrepコマンドを使用する方が良いかどうかご存知ですか?

ベストアンサー1

sed コマンドが機能しない理由は、各行に日付があると仮定するためです。いくつかの行が複数行のエラーメッセージから出た場合はそうではありません。置換パターンに一致する項目がない場合、sed は置換を実行せず、表示される呼び出しスタックのリストは出力に残ります。

先頭に日付を含む行からのみ日付を取得するには、次のオプションがあります。

グレブ:

grep -Eo '^[0-9.]+' fac.log 

-oはgrepに完全な行ではなく一致する部分のみを印刷するように指示し、-Eは「拡張」正規表現を有効にします。

奇妙な:

awk '/^[0-9.]+/ {print $1}' fac.log

awk コマンドの最初の部分は正規表現マッチングで、残りはマッチング行を処理する方法です。ここでは、行の最初の単語を印刷します。

真珠:

perl -lne 'print $1 if /^([0-9]+)/' fac.log

-l:各行に新しい行を印刷しますprint。 -n:各行に実行コマンド(例:awk)を入力します。 -e: ファイルではなくコマンドラインから提供されたことをプログラムに通知します。

すべての場合に一致する各入力行に対して1つの出力行(繰り返し日付)を取得します。結果をパイプする| sort | uniqことは、おそらく重複を排除する最も簡単な方法です。

私は怠惰で、^[0-9.]+より長く正確なパターンを使用しなかったことに注意してください。これは私がsed、awk、友人よりもPerlを使用することを好む理由に関連しています。 Perl正規表現は何をしても常に同じです。また、Perlでは、どの修飾子がデフォルトでサポートされているのか、どの修飾子が-Eなどを設定するのかを覚えておく必要はありません。その後、バージョン間に違いがあります。明らかに、私のDebianシステムはGNU awkの代わりにmawkにデフォルト設定されており、{N}修飾子をサポートしていないため、より正確なモードは機能しません。こんな。

GNU awkのマニュアル:「間隔式は伝統的にawkでは使用できません。これは、awkとegrepが互いに一貫性を持たせるようにPOSIX標準の一部として追加されました。」https://www.gnu.org/software/gawk/manual/html_node/Regexp-Operators.html#Regexp-Operators)

おすすめ記事