ファイルを変更するときに最初、最後の空でない行と空白行をスキップする方法は?

ファイルを変更するときに最初、最後の空でない行と空白行をスキップする方法は?

次のファイルがあります。

H|ACCT|XEC|1|TEMP|20130215035845

849002|48|1208004|100|||1

849007|28|1208004|100|||1

T|2|3



ファイルの末尾には追加の空行があります。

空でない最初の行と最後の行を除くすべての行で、列5の値を列4の値に置き換えたいと思います。

最後の行には他の行と同じ数のフィールドがあり、常に数字で始まる変更された行には依存しないため、フィールドの数に依存することはできません。

次のコードを試しました。

awk 'BEGIN{FS="|"; OFS="|"} {$5=$4; print}' in.txt

出力は次のとおりです

H|ACCT|XEC|1|1|20130215035845
||||
849002|48|1208004|100|100||1
||||
849007|28|1208004|100|100||1
||||
T|2|3||
||||
||||
||||

予想出力:

H|ACCT|XEC|1|TEMP|20130215035845|

849002|48|1208004|100|100||1

849007|28|1208004|100|100||1

T|2|3



変更のために空でない最初の行と最後の行をスキップするにはどうすればよいですか?また、空行をスキップしたいと思います。

ベストアンサー1

awkここでは、ファイルを一度だけ処理するだけです。

awk -F'|' 'NR==1{print;next} m && NF{print m}
    NF{l="\n"$0; $5=$4; m="\n"$0; c=0}; !NF{c++}
END{ print l; for (; i++<c;)print }' OFS='|' infile

説明する:

ここでは、スカイプを介して最初の行を送信し、フィールド5の値をフィールド4の値に置き換えて印刷して実行しますnext

...現在、次の行が空白行ではない場合(少なくとも1つのフィールドを含むNF)、行全体をバックアップして最初に\newlineを追加し、次に5番目のフィールドl="\n"$0の値と4番目のフィールド値を設定し、最後にewlineを追加します。変数に設定します。次の変数があります。$5=$4m\nm="\n"$0;cカウンター!NF{c++}1つ以上のフィールドを持つ行が表示されない場合に空の行数を決定するために使用されるフラグ。それ以外の場合、c=0このカウンタはリセットされます。

mこれで変数の行を修正し、次の実行で設定した場所に印刷し、空の行ではありません(空の行があるときにm && NF{print m}繰り返し印刷を防ぐために使用されます)。awkm& NF

最後に、交換を実行する前に毎回バックアップする最後の最後の行を印刷し、ループフィールドを含む行を見たことEND{ print l; ...のない空の行の数を印刷しますfor (; i++<c;)print }'

余分な空行が必要ない場合は、はるかに短くなります。

awk -F'|' 'NR==1{print;next} m && NF{print m}
    NF{l=$0; $5=$4; m=$0} END{ print l}' OFS='|' infile

おすすめ記事