다음과 같은 필드로 구성된 여러 줄이 포함된 파일이 있습니다.상표:
ID Code Date
1 XX 23/1/2018
1 XX 11/3/2021
2 XX 14/5/2011
2 XX 20/9/2013
3 XX 08/7/2014
3 XX 11/9/2016
3 XX 27/10/2018
ID
열의 날짜가 가장 빠른 항목을 기준으로 각 참가자의 항목을 유지하고 싶습니다 Date
. 각 참가자의 날짜는 빠른 것부터 늦은 것 순으로 정렬됩니다.
내가 원하는 출력은 다음과 같습니다.
1 XX 23/1/2018
2 XX 14/5/2011
3 XX 08/7/2014
답변1
각 참가자의 기록이 가장 오래된 것부터 최신 순으로 정렬되어 있으며 각 참가자에 대해 가장 빠른 날짜의 기록만 인쇄하려고 하므로 ID
이는 각각의 새로운 만남의 첫 번째 기록을 인쇄하는 것과 같습니다 ID
. 이는 다음을 사용하여 쉽게 달성할 수 있습니다 awk
.
awk -F'\t' 'FNR>1 && !seen[$1]++' input.txt
그러면 먼저 필드 구분 기호가 로 설정됩니다 \t
. 그런 다음 사이의 조건을 평가하여 ' ... '
현재 줄을 인쇄할지 여부를 결정합니다. 다음과 같은 경우 한 줄이 인쇄됩니다.
- 1보다 큰 파일당 라인 카운터(헤더 라인을 건너뛰기 위해),그리고
- 배열에는 첫 번째 열( )의 현재 값에 대한 항목이
seen
아직 포함되어 있지 않습니다 .$1
아직 할당되지 않은 배열 값을 역참조하면 로 평가되기 때문에 작동합니다false
. 또한 후위 연산자는++
해당 평가 후에만 적용되므로 특정 첫 번째 발생에 대해서는 true를 반환하지만 0보다 큰ID
후속 발생에 대해서는 반환 하여 줄 인쇄를 억제합니다.seen[$1]
false
헤더 행을 유지하려면 FNR>1
조건을 제거하면 됩니다.
awk -F'\t' '!seen[$1]++' input.txt
ID
( 이 줄 때문에 인쇄됩니다.문자 그대로 ID
, 물론 해당 특정 값이 처음으로 나타나는 경우입니다. )
답변2
다음 용도밀러( mlr
, 구조화된 데이터를 처리하기 위한 도구)을 사용하여 TSV 파일의 레코드를 구문 분석합니다. ID
값과 출력별로 레코드를 그룹화합니다 .첫 번째각 그룹에서 가치를 찾으세요.
$ mlr --tsv head -g ID -n 1 file
ID Code Date
1 XX 23/1/2018
2 XX 14/5/2011
3 XX 08/7/2014
날짜가 다음과 같은 경우아니요각각을 정렬하려면 ID
각 날짜 문자열을 Unix 타임스탬프로 변환하고 이 새 필드를 숫자순으로 정렬하여 각 항목을 정렬할 수 있습니다. 정렬 후에는 위와 동일한 작업을 수행한 다음 타임스탬프 필드를 잘라내(제거)한 후 값을 head
재정렬합니다 .ID
mlr --tsv \
put '$ts = strptime($Date, "%d/%m/%Y")' then \
sort -n ts then \
head -g ID -n 1 then \
cut -x -f ts then \
sort -n ID file
출력은 질문에 표시된 예와 동일합니다.
답변3
다음 코드를 사용하여 원하는 출력을 얻을 수 있습니다.
sed 1d file_of_data | sort -k1,2n -u
이것이 하는 일은,
sed
헤더가 포함된 첫 번째 줄을 삭제(제거)하는 데 사용됩니다.sort
결과 파일은 첫 번째 열에서 숫자순으로 정렬되며 해당 정렬 필드의 중복 항목은 삭제됩니다.
산출
1 XX 23/1/2018
2 XX 14/5/2011
3 XX 08/7/2014