共通文字列「メッセージ」を使用して、特定の順序でテキストを分割します。

共通文字列「メッセージ」を使用して、特定の順序でテキストを分割します。

次の内容を含むテキストファイルがあります。

$ cat foo.txt

some text 
[email protected]
8903457923
2018-02-09 07:12 (Asia/Kolkata)
again some text over here
some more text again
Message
some text 
[email protected]
8903457923
2018-02-05 07:12 (Asia/Kolkata)
again some text over here
some more text again
Message

次の出力を取得したい。

$ cat foo.txt

some text  [email protected]  8903457923  2018-02-09 07:12 (Asia/Kolkata)  again some text over her  some more text again  Message

some text [email protected]  8903457923  2018-02-05 07:12 (Asia/Kolkata) again some text over here  some more text again  Message

私はtrを使用し、「メッセージ」を通常の文字列として使用してこれを達成できると思います。しかし、実装方法がわかりません。

答え1

現在の行が「メッセージ」でない場合は、リストに行を追加し、「メッセージ」が表示されたらOFSに関連付けて現在のリストを印刷します(OFSとして現在の「メッセージ」行に関連付けられています)。

awk '/^Message$/ { print t OFS $0 ORS; t=""; } !/^Message$/ { t=(t ? t OFS $0 : $0) }' < foo.txt

そのt=(t ? t OFS $0 : $0)部分は三項演算子です。tnull の場合は現在の行が割り当てられ、それ以外の場合は現在の値が OFS に追加されます。

出力:

some text  [email protected] 8903457923 2018-02-09 07:12 (Asia/Kolkata) again some text over here some more text again Message

some text  [email protected] 8903457923 2018-02-05 07:12 (Asia/Kolkata) again some text over here some more text again Message

答え2

AWKを使用するより簡単な方法:

awk 'BEGIN { ORS=RS="Message\n" } gsub("\n"," ")' ./in.txt

答え3

使用trsed:

tr '\n' '\t' <foo.txt  | sed -e $'s/Message\\\t/Message\\\n\\\n/g'

これにより、すべての改行文字がタブに変換され、各項目の後に2つの改行文字が追加されます。Message

答え4

最も簡単で直接的な方法は次のとおりです。

 perl -lpe '$\ = /^Message$/ ? "\n\n" : " "' foo.txt

または、awk次のように使用してください。

 awk 'ORS = /^Message$/ ? RS RS : " "'

そのファイルを吸い込んだ後、ファイル全体-0777は1つの大きな文字列になり、正規表現は/(.*?)^(Message\n)/msgそのファイルで機能します。正規表現は、行に隣接する最も短いブロックを調べ、Messageそのブロックをに保存$1し、 nessage 行をに保存します$2。ブロックは、グローバルに空白に置き換えられる改行文字で構成され、この変換結果はtr/\n/ /rに渡されますprintwhileブロック+メッセージ行が見つかる限り、ループは続きます。

perl -ln -0777e 'print $1 =~ tr/\n/ /r, $2 while /(.*?)^(Message\n)/msg' foo.txt

このsedツールを使用して、次のようにこれを実行できます。

sed -e '
    $!N;G;s/\n/ /                ;# put 2 lines in pattern space
    / Message\n$/b               ;# one message block has been found
    s/\(.*\)\(.\)/\2\1/;D        ;# go back to read the next line into pattern space
' foo.txt

関連情報