Unix 쉘 스크립트에서 그룹화 및 최대 기능을 사용하는 방법

Unix 쉘 스크립트에서 그룹화 및 최대 기능을 사용하는 방법

입력하다:

20210602_1234_abc.txt
20210603_1234_def.txt
20210507_5678_abc.txt
20210607_5678_def.txt

산출:

20210603_1234_def.txt
20210607_5678_def.txt

내 스크립트는 먼저 두 번째 열(여기서는 1234 및 5678)을 기반으로 검색한 다음 해당 파일과 연관된 가장 큰 날짜가 있는 파일(이 경우) 20210603 및 20210607을 선택해야 합니다.

UNIX 쉘 스크립트를 통해 어떻게 이를 얻을 수 있습니까?

답변1

zsh셸 의 경우 다음 파일이 현재 디렉터리에 있다고 가정합니다.

$ ls
20210507_5678_abc.txt  20210602_1234_abc.txt  20210603_1234_def.txt  20210607_5678_def.txt
$ typeset -A h; for f (*_*_*.txt) h[${${(s[_])f}[2]}]=$f; print -rC1 - $h
20210603_1234_def.txt
20210607_5678_def.txt

어디

  • 확장자는 *_*_*.txt어휘순으로 정렬되므로 시간순으로 정렬됩니다.
  • ${(s[_])f}분할 $f하다_
  • ${...[2]}이 분할로 인한 두 번째 필드 가져오기
  • h[that]=$fh A: 이 루프에서는 키 연관 배열의 요소에 that전체 파일 이름이 할당됩니다. 정렬로 인해 특정 날짜의 가장 늦은 날짜가 표시됩니다.that
  • print -rC1 -- $h: 열 s의 print해시 값 aw입니다 .r1 C

스크립트를 작성하는 경우 가독성을 높이기 위해 스크립트를 약간 분해할 수 있습니다.

typeset -A max

for file in *_*_*.txt(N); do
  parts=( ${(s[_]file} )
  max[$parts[2]]=$file
done

print -rC1 -- $max

N( glob이 어떤 파일과도 일치하지 않는 경우 오류를 방지하기 위해 (nullglob) glob 한정자가 여기에 추가되었습니다 .)

답변2

입력이 텍스트 파일에서 나온다고 가정하고 사용 awk합니다(질문에서는 어떤 식으로든 이를 지정하지 않았습니다).

$ awk -F '_' 'max[$2] < $1 { max[$2] = $1; maxline[$2] = $0 } END { for (i in maxline) print maxline[i] }' file
20210607_5678_def.txt
20210603_1234_def.txt

_이는 각 입력 행을 -구분된 필드 집합으로 처리합니다 . 이 max배열은 두 번째 필드의 키가 주어지면 첫 번째 필드의 최대값을 추적하며 maxline[i]의 최대값에 해당하는 전체 행입니다 max[i].

키의 새로운 최대값이 발견되면 해당 키의 max합계 maxline값이 모두 업데이트됩니다. 마지막으로 maxline모든 문자열이 인쇄됩니다.


사용 sort:

$ sort -t _ -k 1,1nr file | sort -s -u -t _ -k 2,2
20210603_1234_def.txt
20210607_5678_def.txt

첫 번째는 첫 번째 구분 필드를 기준으로 sort전체 파일을 역순으로 정렬합니다 . _두 번째는 sort두 번째 필드를 정렬하고 해당 필드의 값이 포함된 첫 번째 행만 유지합니다. 이 -u옵션을 사용 sort하면 유틸리티는 이미 본 정렬 키가 있는 행을 삭제하고 -s다음을 보장합니다 .안정적인정렬 알고리즘이 사용되고 있습니다(즉, 동일한 키를 가진 행은 재정렬되지 않음이 보장됩니다).

관련 정보