`awk 'NF {p=1} p'` ファイルの先頭と末尾から空白行を削除するには?

`awk 'NF {p=1} p'` ファイルの先頭と末尾から空白行を削除するには?

(を使用して)ファイルの先頭と末尾から空白行を削除する方法を探している間に、tac次のことがわかりました。

awk 'NF {p=1} p'

これはどのように/なぜ動作しますか?

フィールドがある場合(行が空の行でない場合)のみをNF理解してください。true

ベストアンサー1

これにより、最初から空白行が削除されます。しかし最後からではありません。ファイルの。[注:この答えは質問を修正言及tac]

仕組みは次のとおりです。

  • NF現在行で見つかったフィールドの数。 0の場合、行が空かスペースつまり、最大スペースを含めます(フィールド区切り文字がデフォルト値のままであると仮定し、連続するスペースの数は区切り文字と見なされます)。
  • { ... }ルールブロックの外側(および関連付けられていない)の条件がと評価されると、現在の行が印刷されますtrue。このフラグはp最初は初期化されずに評価されるため、false事前に何も印刷されません。
  • 空でない行が見つかった場合(NFゼロではないと評価されているtrue)、ルールブロックを入力して{p=1}フラグpをに設定します1。その後、pルールブロックの外側が評価され、trueすべての後続の行(現在空でない最初の行を含む)が印刷されます。

気づくこのフラグはpリセットされないため、空でない最初の行以降の空白行はすべてフィルタリングせずに印刷されます。最後の空白行も削除するには、2段階のアプローチを実行する必要があります。

awk 'FNR==NR{if (NF) {if (!first) first=FNR; last=FNR} next}
     FNR>=first && FNR<=last' input.txt input.txt

その後、ファイルは2回処理されます(したがってオペランドとして2回指定されます)。

  • 各ファイルラインカウンタがグローバルラインカウンタFNRと同じ最初のパスでは、空でない最初の行と最後の行を識別します。NR
  • 2番目のパス(FNR今より小さいNR)は、識別された最初の行と空でない最後の行の間の行のみを印刷します。

気づく

で述べたようにStephen Chazerasの答え、2段階の方法は通常のファイルでのみ機能します。入力内容が性格が異なる場合は、ここで提案されているソリューションへのアプローチをご覧ください。

おすすめ記事