次の内容を含むテキストファイルがあります。
$ 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)
部分は三項演算子です。t
null の場合は現在の行が割り当てられ、それ以外の場合は現在の値が 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
使用tr
とsed
:
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
に渡されますprint
。while
ブロック+メッセージ行が見つかる限り、ループは続きます。
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