列が変更された場合は、2行を印刷します。

列が変更された場合は、2行を印刷します。

私はこの質問を見て似たようなことをしたかったです。列の値が変更された場合の行の印刷

デフォルトでは、次の(タブ区切り)ファイルがあります。

A 0 10 loss
A 10 20 loss
A 20 30 loss
A 30 40 no
A 40 50 no
A 50 60 no
A 60 70 no
A 70 80 gain
...

列 4 が "loss" -> "no" または "no" -> "gain" から変更される 2 行を印刷したいので、出力は次のようになります。

A 20 30 loss
A 30 40 no
A 60 70 no
A 70 80 gain

列4の値は何でも可能ですが、変更を含む2行を印刷したいと思います。

これはawkでできるように見えますが、あまり慣れていません。

答え1

これにより、awk次のことができます。

awk 'BEGIN  { getline; cmp=$4; preline=$0 }
     cmp!=$4{ print preline, $0 } { cmp=$4; preline=$0 }' OFS='\n'  infile
A 20 30 loss
A 30 40 no
A 60 70 no
A 70 80 gain

BEGINブロックから最初の行を読み取り、名前付き変数cmpに列#4を格納し、preline後で前の行の列#4を現在の行の列と比較し、変更値があり、preline読み取った値が印刷されます。現在$0の行基準次のブロックは単に現在の行の4番目の列を更新し、次の実行時に行全体を前の行に更新します。

答え2

sedシンボルエディタを使用すると、GNU次のことができます。

sed -Ee '
    $d;N
    /\s(\S+)\n.*\s\1$/!p
    D
' input.file

我々は常にパターン空間に2つの行を持って、N最後のフィールドの遷移を見つける。 1つを検出すると、/\s(\S+)\n.*\s\1$/!p全体のパターンスペースを印刷します。次に、最初Dの部分の使用がこの段階で終了するため、変換の有無にかかわらず、パターン空間の最初の部分を削除します。

制御はsedコードの先頭に移動し、まだeofに達していない場合はプロセスを再度繰り返します。 Eofは操作を停止します$d

出力:

A 20 30 loss
A 30 40 no
A 60 70 no
A 70 80 gain

答え3

なぜしないでください:

$ awk '(NR > 1) && (LAST !~ $4 "$") {print LAST; print $0} {LAST = $0}' file
A 20 30 loss
A 30 40 no
A 60 70 no
A 70 80 gain

関連情報