awk を使用してフィールドの最初と最後の項目を印刷します。

awk を使用してフィールドの最初と最後の項目を印刷します。

タブが外れていますfile

qrs     John    tuv
abcd    Sam     efgh
ijk     Sam     lmnp
abcd    Sam     efgh
ijk     Sam     lmnp
qrs     John    tuv

2番目のフィールドが2番目のフィールドの前の行の値と一致しない行を印刷し、2番目のフィールドが次の行の値と一致しない行を印刷しようとしています。

私は次のようなバリエーションを試しましたが、それらのどれも期待どおりに動作しません。

awk -F"\t" '{
    name=$3;
    line=$0;
    getline;
    newname=$3;
    newline=$0;
    getline;
    nextname=$3;
    nextline=$0; 
    if (newname != name || name != nextname)print line"\n"nextline }' input.txt

答え1

あなたからコメント、次のログイン日とログアウト日を含むログファイルであるとします。

date1   John    logout
date2   Sam     login
date3   Sam     work1
date4   Sam     work2
date5   Sam     logout
date6   John    login

使用awk:

awk 'NR!=1&&$2!=f{print p"\n"$0} {f=$2; p=$0}' file

どこ:

  • NR!=1awk最初の行を除くすべての行を処理するときにTrue(NR現在のファイルの行番号を含む)
  • $2!=f2番目のフィールドを$2変数値ff後で設定)と比較します。
    • 両方の設定が適用されている場合(後で設定する前の行)、改行とawk現在の行の値を印刷します。p\n$0
  • これで各行が処理されます。変数はf2番目のフィールドに設定され、$2変数はp現在の行に設定されます$0。どちらも次の繰り返し(次の行が処理されるとき)で使用されます。

次に、2番目のフィールド(ログアウト、ログイン日、名前など)の最初と最後の項目を印刷します。その後、出力は次のようになります。

date1   John    logout
date2   Sam     login
date5   Sam     logout
date6   John    login

答え2

$2値に変数を指定して、次のコマンドを試してください。

awk -F"\t" 'NR != 1 { if ( x != $2 ) print $0; } { x = $2 }' file

関連情報