私はこの質問を見て似たようなことをしたかったです。列の値が変更された場合の行の印刷
デフォルトでは、次の(タブ区切り)ファイルがあります。
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