神秘的なawkスクリプト接続ライン

神秘的なawkスクリプト接続ライン

空白行で区切られた空でない行の連続ブロックを含むテキストファイルがあります。行をブロックにまとめたい(viエディタの「J」キーに似ています)。ここ タスクを実行する "cfajohnson"で次のスクリプトを見つけました。

awk 'BEGIN { RS = ""; OFS = " "}
           {$1 = $1; print }'

だからファイルを扱う

hello
    world

this
    is
  another
line

与えられた

hello world
this is another line

(2つのSolarisシステム(SunOS 5.11 11.1およびSunOS 5.10 Generic_147440-16)では、ブロックが3つ以上の空行で区切られていると分割エラーが発生します。Linuxでは、2行以上で区切られていると機能します。)

awk(Linux) マニュアルから:

 Assigning a value to an existing field causes 
 the whole record to be rebuilt when $0 is referenced.
...
OFS         The output field separator, a space by default.
...
RS          The input record separator, by default a newline.

省略すると、スクリプトが機能しているようです。

RS=" "

BEGINブロックのステートメント(スペースはRSのデフォルトです)このスクリプトが行を結合して先行スペースと末尾スペースを削除する理由を理解できません。

誰かがこのスクリプトがどのように機能するかを説明できますか?

答え1

省略しても良いと思いますがOFS=" "RS=""awkを入れるには、(またはこれに相当するもの)が必須です。短絡モード

GNUawkマニュアルでは、4.8 マルチラインレコード(私が知っている限り、他のawksも同様に動作します。)

別の技術は、空行でレコードを区切ることです。特別な配列に応じて、RS値は空の文字列になります。これは、レコードが1つ以上の空行に分かれていることを示します。RSが空の文字列に設定されている場合、各レコードは常に最初に表示される空の行で終わります。次のレコードは、空でない最初の行までは開始されません。 1行にいくつかの空白行が表示されても、これはレコード区切り文字として機能します。 (空行は完全に空でなければなりません。スペースのみを含む行は含まれません。)

このモードでは、フィールドはまだデフォルトでスペースで区切られますが、スペースには(単一)改行文字が含まれます。基本出力フィールド区切り文字は単一のスペースであるため、各複数行レコードを単一行スペースで区切られたフィールドに変換するために必要なのは、割り当ての副作用として実装されているawkレコード変数を強制的に再構築することです。はい$0$1=$1有名なawk専門用語の説明、パート2:テキストの変換と交換27.各行から先行スペースと末尾のスペース(トリム)を削除します。

関連情報