조건이 있는 행을 제거하고 여러 열에 값을 중복합니다.

조건이 있는 행을 제거하고 여러 열에 값을 중복합니다.

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

두 번째 쉼표로 구분된 필드가 정확한 문자열이 아닌 경우 현재 줄을 인쇄하거나 eating(두 번째 필드가 eating) 세 번째와 네 번째 필드의 조합이 이전에 표시되지 않은 경우.

논리식

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

다음과 같이 다시 작성할 수 있습니다.

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

(질문에 조건이 명시되는 방식입니다.) 어느 방식이 가장 이해하기 쉬운지에 따라 다릅니다. 이 두 표현은 동일합니다.

이는 다음을 사용하여 원래 레코드 순서를 유지하면서 중복 행을 제거하는 일반적인 관용구의 간단한 변형입니다 awk.

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

답변2

확장 정규식 모드(-E)와 함께 GNU sed를 사용하면 eat에 속하는 튜플(세 번째 및 네 번째 필드)을 두 번째 필드 줄에 유지하여 이 문제를 해결할 수 있습니다. 그런 다음 패턴 공간과 비교하고 적절한 조치를 취합니다.

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

관련 정보