行ブロックが空の行に分割され、行を列に変換する必要があるこのような入力があります。
入力する
HEAD1
IF
FI
GH
HEAD2
PU
GT
HEAD3
FG
DF
YT
GU
次のように印刷する必要があります。
HEAD1 IF FI GH
HEAD2 PU GT
HEAD3 FG DF YT GU
ベストアンサー1
$ awk -v RS='' '{ $1 = $1; print }' file
HEAD1 IF FI GH
HEAD2 PU GT
HEAD3 FG DF YT GU
RS
入力レコード区切り文字がデフォルトの改行文字ではなく空白の場合、awk
入力は入力に表示される2つ以上の連続する改行に基づいてレコードに分割されます。つまり、1 つ以上の空行がレコードの終わりを示すものとして扱われます。これをしばしばawk
「短絡モード」と呼びます。
その後、コードは最初のフィールドを自分自身に設定します。これはランダムな操作のように見えるかもしれませんが、これはawk
現在の出力レコードを書き換えます。ORS
(出力レコード区切り文字)と(出力フィールド区切り文字)のデフォルト値が使用されるため、OFS
(それぞれ改行と空白)レコードが印刷されると、すべてのフィールドは間にスペースがあり、改行で終わる1行に印刷されます。 。
値を変更して、別の文字列または文字で区切られたフィールドを取得できますOFS
。
$ awk -v RS='' -v OFS='\t' '{ $1 = $1; print }' file
HEAD1 IF FI GH
HEAD2 PU GT
HEAD3 FG DF YT GU
$ awk -v RS='' -v OFS=',' '{ $1 = $1; print }' file
HEAD1,IF,FI,GH
HEAD2,PU,GT
HEAD3,FG,DF,YT,GU
$ awk -v RS='' -v OFS='::' '{ $1 = $1; print }' file
HEAD1::IF::FI::GH
HEAD2::PU::GT
HEAD3::FG::DF::YT::GU
このコードは、無条件のデフォルトジョブを呼び出して、後続のために現在のレコードが印刷されるようにawk
短縮できます。これは現在のレコードを無条件に印刷する非常に一般的な方法です。{ $1 = $1 }; 1
1
代わりに使用してくださいsed
:
$ sed -e '/./ { H; $!d; }' -e 'x; y/\n/ /; s/.//' file
HEAD1 IF FI GH
HEAD2 PU GT
HEAD3 FG DF YT GU
H
行に内容が含まれている場合は、現在の行を予約済みスペースに追加します。改行を区切って予約済みスペースに行を追加します。これが入力の最後の行でない場合、パターン空間は廃棄され、d
次の入力行からすぐに開始されます。
現在行が空の場合は、予約済みスペースを次に置き換えx
(パターンスペースが空なので予約済みスペースを消去する効果もあります)、すべての改行を空白に置き換えて最初の文字を削除します(追加文字になります)。空白文字)。