Linux의 디렉토리에서 최신 파일 가져 오기


183

디렉토리에서 가장 최근의 단일 파일을 반환하는 명령을 찾고 있습니다.

에 대한 한계 매개 변수가 보이지 않습니다 ls...


1
watch -n1 'ls -Art | tail -n 1'-가장 최근 파일 표시

여기에있는 대부분의 답변 은 성가신 파일 이름을 처리하는 데 문제가되는 출력 ls또는 사용 find없이 구문 분석합니다 -print0. : 언급 항상 유용 BashFAQ099 는 POSIX의이 문제에 대한 답변을 제공합니다
kvantour을

답변:


266
ls -Art | tail -n 1

매우 우아하지는 않지만 작동합니다.


2
ls -Artls를 사용하여 파일 날짜를 볼 수도 있습니다.
Josir

13
사소한 문제 : 모든 버전 파이프의 출력 ls으로는 tail, 다음 마지막 행을 인쇄합니다. IMHO 오름차순으로 정렬 head하고 chaos제안 된 대로 대신 사용하는 것이 좋습니다. 첫 번째 라인 헤드를 인쇄 한 후에는 다음 라인 (실제로 다음 블록)을 보내면 SIGPIPE가 상승하고 ls종료됩니다.
TrueY

1
@TrueY 동의합니다. 혼돈의 대답은 효율성에 더 좋습니다.
dmckee --- 전 운영자 고양이 새끼 고양이

2
이 솔루션에는 파일뿐만 아니라 디렉토리도 포함되어 있습니다. 이것은 좋은 일이거나 나쁜 일이 될 수 있습니다. 개별 사용자가 원하는 것에 따라 다릅니다. 내가 이것을 제기하는 이유는 원래 질문에 "파일"이 있기 때문입니다.
Sildoreth

2
head 대신 tail을 사용하는 의도 된 이점은 ls가 반환 한 총계를 나타내는 줄을 포함하지 않는 것입니다.
피터 스콧

155
ls -t | head -n1

이 명령은 실제로 현재 작업 디렉토리의 최신 수정 파일을 제공합니다.


내 것과 동일하며 더 효율적일 수도 있습니다.
dmckee --- 전 운영자 고양이

내 첫 번째 정보를 먼저 출력하기 때문에 꽤 효과가 없지만 사용법을 얻습니다. 감사합니다!
ack

4
@Josir 이것은 날짜 스탬프를 포함하도록 수정 될 수 있으며 ls -tl | head -n 1, 내 방식대로 파이프를 통해 전체 테이블을 푸시하지 않아도됩니다.
dmckee --- 전 운영자 고양이 새끼

1
@ noɥʇʎԀʎzɐɹƆls -t *.png | head -n1
혼돈

4
가장 최근에 수정 된 폴더 인 경우 다음을 사용합니다. ls -Art | head -n1최근에 수정 한 파일을 원할 경우
achasinh

79

이것은 재귀 버전입니다 (즉, 특정 디렉토리 또는 하위 디렉토리에서 가장 최근에 업데이트 된 파일을 찾습니다)

find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1

편집 : Kevin이 제안한 -f 2-대신 사용하십시오.-f 2


5
Mac 용 솔루션은 다음과 같습니다.find $DIR -type f -exec stat -lt "%Y-%m-%d" {} \+ | cut -d' ' -f6- | sort -n | tail -1
사용자

2
cut 명령은 -f 2 대신 공백으로 경로를 자릅니다. -f2-를 사용하여 필드 2를 줄 끝으로 되돌립니다.
Kevin

2
혼돈에 의한 제안 에서처럼을 사용하여 정렬을 반대로하면 대신 대신 sort -nr사용 하여 효율성을 향상시킬 수 있습니다. (재귀 적 검색을 정렬하는 경우에도 첫 번째 또는 마지막 줄을 얻는 것이 느린 것은 아닙니다.)head -n 1tail -n 1
destenson

2
굉장히 유용하다! ls로 파이프하면 더 친숙합니다.find ./ -type f -printf "%T@ %p\n" -ls | sort -n | cut -d' ' -f 2- | tail -n 1 | xargs -r ls -lah
Simon

@user의 Mac 버전은 시간이 아닌 날짜 만 정렬 / 표시합니다. 고정 버전은 다음과 같습니다.find $DIR -type f -exec stat -lt "%F %T" {} \+ | cut -d' ' -f6- | sort -n | tail -1
yoz

11

신뢰성에 대한 참고 사항 :

개행 문자는 파일 이름에서와 같이 유효하므로 / 기반 과 같은 행에 의존하는 솔루션 에는 결함이 있습니다.headtail

GNU ls에서 다른 옵션은 --quoting-style=shell-always옵션과 bash배열 을 사용하는 것입니다 .

eval "files=($(ls -t --quoting-style=shell-always))"
((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

( 숨겨진 파일도 고려 하려면 -A옵션을 추가하십시오 ls).

일반 파일 (디렉토리, fifo, 장치, 심볼릭 링크, 소켓 무시)로 제한하려면 GNU를 사용해야합니다 find.

bash 4.4 이상 (for readarray -d) 및 GNU coreutils 8.25 이상 (for cut -z) :

readarray -t -d '' files < <(
  LC_ALL=C find . -maxdepth 1 -type f ! -name '.*' -printf '%T@/%f\0' |
  sort -rzn | cut -zd/ -f2)

((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

또는 재귀 적으로 :

readarray -t -d '' files < <(
  LC_ALL=C find . -name . -o -name '.*' -prune -o -type f -printf '%T@%p\0' |
  sort -rzn | cut -zd/ -f2-)

여기서 가장 번거 로움을 피하는 zsh대신에 글로브 한정자 를 사용하는 것이 가장 좋습니다 bash.

현재 디렉토리의 최신 일반 파일 :

printf '%s\n' *(.om[1])

숨겨진 것 포함 :

printf '%s\n' *(D.om[1])

두 번째 최신 :

printf '%s\n' *(.om[2])

심볼릭 링크 해결 후 파일 수명 확인 :

printf '%s\n' *(-.om[1])

재귀 적으로 :

printf '%s\n' **/*(.om[1])

또한 완성 시스템 (compinit 및 co)을 사용 Ctrl+Xm하면 최신 파일로 확장되는 완료자가됩니다.

그래서:

vi Ctrl+Xm

최신 파일을 편집하게 하시겠습니까 (누르기 전에 파일을 볼 수도 있습니다) Return ).

vi Alt+2Ctrl+Xm

두 번째로 작은 파일입니다.

vi * .cCtrl+Xm

최신 c 파일.

vi * (.)Ctrl+Xm

최신 일반 파일 (디렉토리 나 fifo / 장치가 아님) 등.


zsh팁 주셔서 감사합니다 . zsh docs에서 이에 대한 자세한 내용에 대한 링크를 제공 할 수 있습니까?
동결 됨

@freezed, 참조info zsh qualifiers
Stephane Chazelas

감사합니다 @Stephane Chazelas
동결 됨

9

나는 사용한다:

ls -ABrt1 --group-directories-first | tail -n1

폴더를 제외한 파일 이름 만 알려줍니다.


디렉토리는 디렉토리를하지 않는 한
ealfonso

8

ls -lAtr | tail -1

다른 솔루션에는로 시작하는 파일이 포함되어 있지 않습니다 '.'.

이 명령에는 '.'and 가 포함 되며 '..', 원하는대로 또는 아닐 수도 있습니다.

ls -latr | tail -1


이 사람이 "."을 반환합니까? 디렉토리가 포함 된 파일보다 최근에 디렉토리를 수정 한 경우 (예 : 삭제)? 아마도 이것이 원하는 행동 일 수도 있고 아닐 수도 있습니다. 그러나 당신은 어느 쪽이든 맞습니다.
dmckee --- 전 운영자 고양이


5

나는 단지 파일 이름을 제공하고 다른 명령을 호출하지 않기 때문에 echo *(om[1])( zsh구문)을 좋아한다 .


1
zsh를 사용하는 경우 제대로 작동합니다. zsh를 사용하지 않습니까? 우분투에서는 bash가 기본값이라고 생각합니다. zsh를 설치하거나 bash에 해당하는 명령을 찾을 수 있습니다.
MikeB

3
명령은 "echo"입니다. 단지 매개 변수를 평가하여 표준 출력으로 보냅니다. 이 경우, glob 한정자 "om [1]"에는 "o"가 있습니다. 이는 "m"을 기준으로 일치하는 파일의 순서를 의미하며 수정 된 시간입니다. 그리고 그 순서 목록에서 첫 번째 파일 인 [1]을 선택하십시오. glob 한정자에 대해 읽을 수 있습니다. zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers
MikeB

4

찾기 / 정렬 솔루션은 전체 파일 시스템과 같이 파일 수가 실제로 커질 때까지 훌륭하게 작동합니다. 가장 최근 파일을 추적하려면 대신 awk를 사용하십시오.

find $DIR -type f -printf "%T@ %p\n" | 
awk '
BEGIN { recent = 0; file = "" }
{
if ($1 > recent)
   {
   recent = $1;
   file = $0;
   }
}
END { print file; }' |
sed 's/^[0-9]*\.[0-9]* //'

3

필자는 개인적으로 가능한 많은 내장 bash명령 을 사용하는 것을 선호합니다 (고가의 포크 및 exec syscall 수를 줄이기 위해). 날짜별로 정렬하려면ls 호출해야합니다. 그러나의 사용은 head실제로 필요하지 않습니다. 나는 다음의 한 줄짜리 라이너를 사용합니다 (이름 파이프를 지원하는 시스템에서만 작동합니다).

read newest < <(ls -t *.log)

또는 가장 오래된 파일의 이름을 얻기 위해

read oldest < <(ls -rt *.log)

(두 '<'표시 사이의 간격을 염두에 두십시오!)

숨겨진 파일도 필요한 경우 -Arg를 추가 할 수 있습니다.

이것이 도움이되기를 바랍니다.


파일 이름이 $ oldest / newest var에 저장되어 있음을 설명해야합니다. 그러나 가장 적은 양의 포크는 +1입니다.
squareatom

@ squareatom 나는 읽은 것이 꽤 잘 내장되어 있다고 생각했다. 하지만 당신 말이 맞을 수도 있습니다. 귀하의 의견에 감사드립니다!
TrueY

3
내장이 무엇인지 알고 있다고 가정하면 정확합니다. 그러나 OP의 질문에 대해서만 생각했습니다. 그들은 무언가를 돌려 줄 명령을 요구했습니다. 기술적으로 귀하의 솔루션은 아무것도 출력하지 않습니다. 따라서 "&& echo $ newest"또는 끝에 유사한 것을 추가하십시오 ;-)
squareatom


2
ls -t -1 | sed '1q'

폴더에서 마지막으로 수정 된 항목을 표시합니다. grep키워드와 함께 최신 항목을 찾으 려면와 페어링

ls -t -1 | grep foo | sed '1q'

'1q'는 무엇입니까? 1첫 번째 줄 head -n 1은 q가 무엇입니까?
HattrickNZ

2

재귀 적으로 :

find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head

1

이 간단한 명령을 시도

ls -ltq  <path>  | head -n 1

파일 이름-마지막 수정을 원할 경우 path = /ab/cd/*.log

디렉토리 이름-최종 수정을 원하는 경우 경로 = / ab / cd / * /


1

로 시작하는 숨겨진 파일은 신경 쓰지 않는다고 가정 .

ls -rt | tail -n 1

그렇지 않으면

ls -Art | tail -n 1

1

BashFAQ / 003을 따르는 Bash 내장 기능 만 있습니다 .

shopt -s nullglob

for f in * .*; do
    [[ -d $f ]] && continue
    [[ $f -nt $latest ]] && latest=$f
done

printf '%s\n' "$latest"

0

모든 ls / tail 솔루션은 파일의 파일에 완벽하게 작동합니다 . 하위 디렉토리를 무시 - 디렉토리.

검색에 모든 파일을 재귀 적으로 포함 시키려면 찾기를 사용할 수 있습니다. gioele는 형식이 지정된 찾기 출력 정렬을 제안했습니다. 그러나 공백에주의하십시오 (그의 제안은 공백과 작동하지 않습니다).

이것은 모든 파일 이름에서 작동합니다.

find $DIR -type f -printf "%T@ %p\n" | sort -n | sed -r 's/^[0-9.]+\s+//' | tail -n 1 | xargs -I{} ls -l "{}"

이것은 mtime을 기준으로 정렬합니다. man find 참조 :

%Ak    File's  last  access  time in the format specified by k, which is either `@' or a directive for the C `strftime' function.  The possible values for k are listed below; some of them might not be available on all systems, due to differences in `strftime' between systems.
       @      seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
%Ck    File's last status change time in the format specified by k, which is the same as for %A.
%Tk    File's last modification time in the format specified by k, which is the same as for %A.

그러니 그냥 교체 %T%Cctime을 기준으로 정렬.


당신은 @gioele 제안과 공백 문제에 대한 정확하지만, 당신은 단지 것을 수정에 그것을 범위를 확인하기 위해 -f 옵션에 하이픈을 추가해야합니다 find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1 , 첫 번째 필드를 제외한 모든 유지 또는 대안 : find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 1 --complement | tail -n 1
아론

0

패턴에 따라 모든 디렉토리에서 최신 파일 찾기 (예 : "tmp"로 끝나는 작업 디렉토리의 하위 디렉토리 (대소 문자 구분)) :

find . -iname \*tmp -type d -exec sh -c "ls -lArt {} | tail -n 1" \;

0
ls -Frt | grep "[^/]$" | tail -n 1

1
OP의 질문을 제공하는 다른 답변이 있으며 몇 년 전에 게시되었습니다. 답변을 게시 할 때는 특히 오래된 질문에 답변 할 때 새로운 솔루션을 추가하거나 실질적으로 더 나은 설명을 추가해야합니다.
help-info.de

2
@ help-info.de 코드 전용 답변을 삭제하려면 투표하지 마십시오. 그것들은 훌륭하지는 않지만 삭제는 답이 아닌 것들을위한 것입니다
Machavity

@ Machavity-나는 실패하지 않았기를 바랍니다.
help-info.de

0

하위 디렉토리를 포함하여 가장 최근에 변경된 파일을 얻으려면이 작은 oneliner로 수행 할 수 있습니다.

find . -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk -v var="1" 'NR==1,NR==var {print $0}' | while read t f; do d=$(date -d @$t "+%b %d %T %Y"); echo "$d -- $f"; done

변경된 파일에 대해 동일하지 않고 액세스 된 파일에 대해 동일한 작업을 수행하려면

%의 Y 로부터 변수 통계 명령 %의 X . 가장 최근에 액세스 한 파일에 대한 명령은 다음과 같습니다.

find . -type f -exec stat -c '%X %n' {} \; | sort -nr | awk -v var="1" 'NR==1,NR==var {print $0}' | while read t f; do d=$(date -d @$t "+%b %d %T %Y"); echo "$d -- $f"; done

둘 이상의 파일을 나열하려는 경우 두 명령 모두에서 var = "1" 매개 변수를 변경할 수도 있습니다 .


-1

나도 그것을해야했고,이 명령을 찾았습니다. 이것들은 나를 위해 일합니다 :

폴더에 생성 날짜별로 마지막 파일을 원할 경우 (액세스 시간) :

ls -Aru | tail -n 1  

그리고 내용이 변경된 마지막 파일을 원한다면 (수정 시간) :

ls -Art | tail -n 1  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.