![동일한 두 필드가 있는 행을 찾고 그 중 하나만 제외하고 모두 삭제하는 방법 [중복]](https://linux55.com/image/114853/%EB%8F%99%EC%9D%BC%ED%95%9C%20%EB%91%90%20%ED%95%84%EB%93%9C%EA%B0%80%20%EC%9E%88%EB%8A%94%20%ED%96%89%EC%9D%84%20%EC%B0%BE%EA%B3%A0%20%EA%B7%B8%20%EC%A4%91%20%ED%95%98%EB%82%98%EB%A7%8C%20%EC%A0%9C%EC%99%B8%ED%95%98%EA%B3%A0%20%EB%AA%A8%EB%91%90%20%EC%82%AD%EC%A0%9C%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%20%5B%EC%A4%91%EB%B3%B5%5D.png)
이 질문을 여러 부분으로 나누면 더 쉬울 것 같아요.
- 첫 번째 필드의 값이 같고 마지막 필드의 값이 같은 행을 찾는 방법이 있나요? - 하지만 반드시 서로 같을 필요는 없나요?
선:
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
- 동일한 첫 번째 필드와 마지막 필드가 중복되는 행을 제외한 모든 행을 삭제하는 방법이 있습니까?
앞으로:
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