동일한 두 필드가 있는 행을 찾고 그 중 하나만 제외하고 모두 삭제하는 방법 [중복]

동일한 두 필드가 있는 행을 찾고 그 중 하나만 제외하고 모두 삭제하는 방법 [중복]

이 질문을 여러 부분으로 나누면 더 쉬울 것 같아요.

  1. 첫 번째 필드의 값이 같고 마지막 필드의 값이 같은 행을 찾는 방법이 있나요? - 하지만 반드시 서로 같을 필요는 없나요?

선:

  AAAAA stuff in between BBBBB
  AAAAA more stuff in the middle CCCCCC
  AAAAA even more cool stuff BBBBB

관심 라인:

  AAAAA stuff in between BBBBB
  AAAAA even more cool stuff BBBBB
  1. 동일한 첫 번째 필드와 마지막 필드가 중복되는 행을 제외한 모든 행을 삭제하는 방법이 있습니까?

앞으로:

  AAAAA stuff in between BBBBB
  AAAAA more stuff in the middle CCCCCC
  AAAAA even more cool stuff BBBBB

뒤쪽에:

  AAAAA stuff in between BBBBB
  AAAAA more stuff in the middle CCCCCC

솔루션을 단순화하기 위해 파일을 약간 조작할 수 있습니다(예: 고정된 수의 필드 설정).

현재 파일에는 줄당 필드 수가 다르지만 첫 번째 필드와 마지막 필드가 중요합니다.

모든 필드 사이에는 공백이 있습니다.

awk에 대한 일부 참조를 검색하여 찾았지만 이런 방식으로 여러 필드를 사용하는 awk의 예를 찾을 수 없습니다.

매우 감사합니다.

답변1

GNUAWK

다음은 약간 수정된 입력 파일을 사용한 테스트 실행입니다.

bash-4.3$ $ awk '{v=sprintf("%s_%s",$1,$NF); if ( ! a[v]) print;   a[v]++;   }' input.txt 
bash: $: command not found
bash-4.3$ awk '{v=sprintf("%s_%s",$1,$NF); if ( ! a[v]) print;   a[v]++;   }' input.txt 
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC

bash-4.3$ cat input.txt
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC
AAAAA even more cool stuff BBBBB
AAAAA extra line CCCCCC

작동 원리:

  • 요점: 키-값 쌍의 배열을 만들고 키-값 쌍의 배열 항목이 이미 있는지 여부에 따라 인쇄합니다.
  • 키는 행의 마지막 필드 v=sprintf("%s_%s",$1,$NF)에서 구성 됩니다 $NF. 예를 들어 행 1과 3의 경우 키는 입니다 AAAAABBBBB. 값은 일치할 때마다 증가하는 정수입니다.
  • v각 줄에서 변수와 해당 검사를 수행 if (!a[v]) print하고 배열에서 값을 찾을 수 없는 경우에만 인쇄합니다.
  • a[v]++인쇄 여부에 관계없이 모든 줄에서 실행됩니다

Sundeep이 의견에서 지적했듯이 동일한 접근 방식을 다음과 같이 단순화할 수 있습니다.

bash-4.3$ awk '!seen[$1"_"$NF]++' input.txt
AAAAA stuff in between BBBBB
AA stuff AAABBBBB
AAAAA more stuff in the middle CCCCCC

관련 정보