아래와 같은 파일이 있습니다
1,1230,add
1,1235,remove
2,1240,add
2,1245,remove
3,1250,add
4,1255,remove
첫 번째 필드에 고유한 값이 있는 행을 인쇄하고 싶습니다.그리고여기서 세 번째 필드는 다음과 같습니다 add
. 이 예의 예상 출력은 다음과 같습니다.
3,1250,add
또는 첫 번째 열만, 즉
3
아래 명령은 다른 레코드를 제공하지만 세 번째 열이 "추가"되었는지 확인한 다음 출력을 인쇄하고 싶습니다.
awk -F ',' 'print $1' filename | uniq -u
답변1
이 경우 나는 이중 패스 접근 방식을 생각했습니다.
awk -F',' 'NR==FNR{seen[$1]++;next} $3=="add" && seen[$1]==1' file.txt file.txt
그러면 입력 파일이 두 번 처리됩니다(따라서 매개변수로 두 번 선언됩니다).
- 첫 번째 패스에서
NR
전역 행 카운터는FNR
파일별 행 카운터와 동일하며 첫 번째 필드의 이 특정 값이 발견되는 빈도만 계산합니다. 그렇지 않으면 처리(명령문next
)를 즉시 건너뜁니다. - 두 번째 패스에서는 세 번째 필드가 동일한지
add
, 첫 번째 필드가 한 번만 나타나는지 확인합니다. 그렇다면 해당 행을 인쇄합니다(두 조건 모두 로 평가되므로true
).
답변2
AdminBee가 이미 이 awk
방법을 시연했으므로 표준 유틸리티를 사용하는 또 다른 방법이 있습니다.
sort -t',' -k1,1 file | uniq -u -w 1 | grep 'add$'
sort
쉼표를 구분 기호로 사용하고 필드 1로만 정렬uniq
고유한 줄만 인쇄하되 1개(!) 줄당 문자 수- 이제
grep
"add"로 끝나는 줄
제한 사항: uniq
물론 한 문자만 확인됩니다. 필드 1에 두 개 이상의 숫자 항목이 있는 경우 필드 1은 왼쪽을 0으로 채운 다음 그에 따라 확인하는 데 사용되는 문자 수를 늘리는 등 사전 처리되어야 합니다. 예제에 제공된 대로 파일이 이미 정렬되어 있는 경우 정렬을 건너뛸 수 있습니다.
답변3
한 번에 모든 작업을 수행하려면 awk를 사용하세요.
awk -F ',' '
{ if ( ! seen[$1]++ )
{ if ( $3 == "add" )
keep[$1] = $0
}
else
{
if ( keep[$1] )
delete keep[$1]
}
}
END {
for (i in keep)
print keep[i]
}' infile