이 질문을 여러 부분으로 나누면 더 쉬울 것 같아요.
- 첫 번째 필드의 값이 같고 마지막 필드의 값이 같은 행을 찾는 방법이 있나요? - 하지만 반드시 서로 같을 필요는 없나요?
선:
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