条件付きの行を削除し、複数の列に値を重複します。

条件付きの行を削除し、複数の列に値を重複します。

2列だけを「食べる」と、3列と4列の結合値がすでに前の行にある条件付き行を削除する必要があります。

私のサンプルデータCSVは次のとおりです。

a,eating,apple,2
b,throwing,banana,1
c,eating,apple,3
d,eating,apple,1
e,eating,banana,2
f,throwing,apple,2
g,throwing,banana,2
h,throwing,banana,3
i,eating,apple,2
j,eating,apple,3
k,eating,banana,1
l,throwing,banana,2
m,throwing,banana,1
n,throwing,apple,1
o,eating,apple,3
p,eating,banana,2
q,throwing,apple,1
r,throwing,apple,2
s,eating,apple,1

出力は次のようにする必要があります

a,eating,apple,2
b,throwing,banana,1
c,eating,apple,3
d,eating,apple,1
e,eating,banana,2
f,throwing,apple,2
g,throwing,banana,2
h,throwing,banana,3
k,eating,banana,1
l,throwing,banana,2
m,throwing,banana,1
n,throwing,apple,1
q,throwing,apple,1
r,throwing,apple,2

答え1

入力データが「一般CSV」であると仮定すると、つまり、どのフィールドにもカンマや改行が含まれていないと仮定すると、awk次のように使用できます。

$ awk -F, '$2 != "eating" || !seen[$3,$4]++' file
a,eating,apple,2
b,throwing,banana,1
c,eating,apple,3
d,eating,apple,1
e,eating,banana,2
f,throwing,apple,2
g,throwing,banana,2
h,throwing,banana,3
k,eating,banana,1
l,throwing,banana,2
m,throwing,banana,1
n,throwing,apple,1
q,throwing,apple,1
r,throwing,apple,2

2番目のカンマ区切りフィールドが正しい文字列でない場合は、現在の行を印刷するかeating(2番目のフィールドはい eating) 3番目と4番目のフィールドの組み合わせが以前に表示されていない場合。

論理式

$2 != "eating" || !seen[$3,$4]++

次のように書き換えることができます。

!($2 == "eating" && seen[$3,$4]++)

(質問に条件が記載されている方法です。)どの方法が最も理解しやすいかによって異なります。これら2つの表現は同じです。

これは、次のように元のレコードの順序を維持しながら重複行を削除する一般的なイディオムの簡単なバリエーションですawk

awk '!seen[$0]++' file

答え2

拡張正規表現モード(-E)でGNU sedを使用すると、eatに属するタプル(3番目と4番目のフィールド)を2番目のフィールド行に保持することでこの問題を解決できます。その後、パターン空間と比較し、適切な処置をとる。

sed -E '
  /\n/{
    s///;s/\n+/\n/g
  h;d;}
  /^[^,]+,eating,/{
    s/[^,]+/&\n/4;T
    s/[^,]+/\n&/3;G
    /(\n.+\n).*\1/d
    h;s/\n//;s///;P
  x;D;}
' file

関連情報