newer.sh
파일 목록이 주어지면 최신 파일을 반환 하는 스크립트를 작성해야 합니다 . 즉, 다음을 입력합니다.
newer.sh /some/file other-file /and/so/on
목록의 최신 파일 이름을 반환합니다.
지금까지 제가 생각할 수 있는 것은 다음과 같습니다.
#!/bin/bash
echo "Newest file:"
ls -t | head -n 1
실제로 생성 시간을 기준으로 생성된 최신 파일을 반환하지만 현재 디렉터리의 파일에만 해당됩니다.
답변1
GNU 도구 사용:
#! /bin/bash -
export LC_ALL=C
eval "files=($(ls -dt --quoting-style=shell-always -- "${@?}"))"
((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"
기호 링크의 경우 기호 링크 자체의 마지막 수정 시간을 고려합니다. 심볼릭 링크의 대상이 되도록 하려면 -L
이 옵션을 ls
.
인수로 제공된 파일 경로에 개행 문자를 포함할 수 없다는 제한을 추가하려면 다음과 같이 작성할 수 있습니다.
#! /bin/sh -
# only works for file paths that don't contain newline characters
[ "$#" -gt 0 ] && ls -td -- "$@" | head -n 1
GNU 도구에 대한 의존성을 제거합니다.
원칙은 동일합니다. 사용된 함수는 ls -t
수정 시간을 기준으로 파일을 정렬하고 해당 목록의 첫 번째 파일을 가져옵니다. 그러나 여기서는 한 줄에 하나의 파일 목록이 출력되므로 파일 경로에 개행 문자가 포함되어 있지 않다는 것을 보장할 수 없으면 안정적으로 구문 분석할 수 없습니다(그렇지 않으면 및 이름 이 지정된 두 파일을 ls
구별할 수 없습니다). 최신 파일 ) 실제로 제공된 잘못된 결과 .a<newline>b
a
b
a<newline>b
head -n 1
a
귀하의 접근 방식과 달리 여기서는 스크립트가 수신하는 인수 목록을 "$@"
전달하고 ls
( --
인수가 ls
옵션이 아닌 파일 피연산자로 처리되도록 a 뒤에) -d
옵션이 ls
나열되지 않도록 전달합니다.콘텐츠이 파일의 유형목차. 또한 스크립트가 0개의 인수( == 0)를 받는 경우에도 $#
이 작업을 수행하지 않습니다. 그렇지 않으면 ls -td --
현재 디렉터리가 나열되므로 .
출력을 얻습니다.
GNU 외에도 GNU를 사용하여 정렬할 수 있는 방식으로 파일의 수정 시간을 검색하기 위해 ls
GNU를 사용할 수도 있습니다 .stat
sort
#! /bin/sh -
export TZ=UTC0 LC_ALL=C
stat --printf '%y@%n\0' -- "$@" | sort -rz | sed -z 's/^[^@]*@//;q' | tr '\0' '\n'
sed
( 에는 최신 버전의 GNU를 사용하십시오 -z
.) 또는 GNU를 사용하십시오 awk
:
#! /bin/sh -
export TZ=UTC0 LC_ALL=C
stat --printf '%y@%n\0' -- "$@" | awk -v RS='\0' '
NR == 1 || $0 > newest {newest = $0}
END {if (NR) {sub(/[^@]*@/, "", newest); print newest}}'