입력하다:
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]=$f
h
A
: 이 루프에서는 키 연관 배열의 요소에that
전체 파일 이름이 할당됩니다. 정렬로 인해 특정 날짜의 가장 늦은 날짜가 표시됩니다.that
print -rC1 -- $h
: 열 s의print
해시 값 aw입니다 .r
1
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
다음을 보장합니다 .안정적인정렬 알고리즘이 사용되고 있습니다(즉, 동일한 키를 가진 행은 재정렬되지 않음이 보장됩니다).