파일 목록에서 최신 항목을 찾는 스크립트

파일 목록에서 최신 항목을 찾는 스크립트

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>baba<newline>bhead -n 1a

귀하의 접근 방식과 달리 여기서는 스크립트가 수신하는 인수 목록을 "$@"전달하고 ls( --인수가 ls옵션이 아닌 파일 피연산자로 처리되도록 a 뒤에) -d옵션이 ls나열되지 않도록 전달합니다.콘텐츠이 파일의 유형목차. 또한 스크립트가 0개의 인수( == 0)를 받는 경우에도 $#이 작업을 수행하지 않습니다. 그렇지 않으면 ls -td --현재 디렉터리가 나열되므로 .출력을 얻습니다.

GNU 외에도 GNU를 사용하여 정렬할 수 있는 방식으로 파일의 수정 시간을 검색하기 위해 lsGNU를 사용할 수도 있습니다 .statsort

#! /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}}'

관련 정보