디렉토리에서 최신 수정 파일을 재귀 적으로 찾는 방법은 무엇입니까?


답변:


357
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "

거대한 나무의 경우 sort모든 것을 메모리에 보관하기 가 어려울 수 있습니다 .

%T@유닉스 타임 스탬프와 같은 수정 시간을 제공하고, sort -n숫자로 정렬 tail -1하고, 마지막 라인 (가장 높은 타임 스탬프)을 취하고 cut -f2 -d" ", 출력에서 ​​첫 번째 필드 ( 타임 스탬프)를 잘라냅니다.

편집 : 것처럼 -printf아마의 GNU 전용 ajreals 사용하다 stat -c너무. BSD에서도 같은 작업을 수행 할 수 있지만 포맷팅 옵션이 다릅니다 ( -f "%m %N"보여 질 것입니다)

그리고 나는 복수의 일부를 놓쳤다. 당신이 더 많은 그런 다음 원하는 경우 최신 파일을 바로 꼬리 인수를 범프.


7
주문이 중요한 경우 sort -rn | head -3대신 대신 사용 을 전환 할 수 있습니다 sort -n | tail -3. 하나의 버전은 파일을 가장 오래된 것부터 가장 오래된 것으로, 다른 버전은 가장 오래된 것부터 가장 오래된 것까지 제공합니다.
Don Faulkner

3
나는 거대한 디렉토리 (약 10 만 개의 작은 파일)를 가지고 있었고 성능에 대해 걱정했지만 ...이 명령은 1 초 이내에 실행됩니다! 큰 감사합니다 !!! :-)
lucaferrario

2
"거대한 나무의 경우 모든 것을 메모리에 보관하는 것이 어려울 수 있습니다." 필요에 따라 sort임시 파일 ( /tmp)을 만들 것이므로 걱정하지 않아도됩니다.
블라디미르 판 텔레 예프

1
그것을 수정 : -printf '%T@ %Tb %Td %TY %p\n'날짜 스탬프를 제공합니다 (필요한 경우) (와 유사 ls)
bshea

1
나는 다음과 같이 더 짧고 해석하기 find . -type f -printf '%TF %TT %p\n' | sort | tail -1
쉬운

129

@ plundra 's answer 다음에 BSD 및 OS X 버전이 있습니다.

find . -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" "

1
BSD / OS X가 대신 find지원 합니까? 파이프 없이 동일한 작업을 수행하기 때문에 (여러 파일을 매개 변수로 전달) . +\;-print0 | xargs -0
DevSolar

내림차순으로 수정 된 마지막 5 개 또는 n 개의 파일 수를 얻으려면 어떻게해야합니까?
khunshan

@khunshan 변경 head -1으로head -5
에머슨 Farrugia

20

결과를 정렬하고 마지막으로 수정 된 결과 만 유지하는 대신 awk를 사용하여 수정 시간이 가장 큰 결과 만 인쇄 할 수 있습니다 (유닉스 시간).

find . -type f -printf "%T@\0%p\0" | awk '
    {
        if ($0>max) {
            max=$0; 
            getline mostrecent
        } else 
            getline
    } 
    END{print mostrecent}' RS='\0'

파일 수가 충분하면 문제를 해결하는 가장 빠른 방법입니다.

이론적으로 파일 이름에는 공백과 줄 바꿈을 포함한 모든 문자가 포함될 수 있지만 NUL 문자 (예 : '\ 0')를 사용했습니다.

시스템에 병리학 적 파일 이름이 없으면 줄 바꿈 문자도 사용할 수 있습니다.

find . -type f -printf "%T@\n%p\n" | awk '
    {
        if ($0>max) {
            max=$0; 
            getline mostrecent
        } else 
            getline
    } 
    END{print mostrecent}' RS='\n'

또한 이것은 멍청이에서도 작동합니다.


이것은 가장 최근의 세 가지를 유지하도록 쉽게 조정할 수 있습니다.
추후 공지가있을 때까지 일시 중지되었습니다.

1
mawk데비안 표준 대안 인에서는 작동하지 않습니다 .
Jan

아니요, 그러나이 경우 줄 바꿈 문자를 사용하지 않으면 줄 바꿈 문자를 사용할 수 있습니다.)
marco

10

나는이 솔라리스 10에서 마지막으로 수정 된 파일을 찾을 수있는 문제가 있었다 find이없는 printf옵션 및 stat사용할 수 없습니다입니다. 나는 나에게 잘 맞는 다음 해결책을 발견했다.

find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1

파일 이름을 표시하려면

find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1

설명

  • find . -type f 모든 파일을 찾아서 나열합니다
  • sed 's/.*/"&"/' 공백을 처리하기 위해 경로 이름을 따옴표로 묶습니다.
  • xargs ls -E에 인용 된 경로를 전송 ls, -E옵션은 풀 타임 스탬프 (형식 있는지 확인합니다 년 - 월 - 일시 - 분 - 초 - 나노초가 ) 반환
  • awk '{ print $6," ",$7 }' 날짜와 시간 만 추출
  • awk '{ print $6," ",$7," ",$9 }' 날짜, 시간 및 파일 이름 추출
  • sort 날짜별로 정렬 된 파일을 반환합니다
  • tail -1 마지막으로 수정 된 파일 만 반환

9

하위 디렉토리에서도 잘 작동하는 것 같습니다.

find . -type f | xargs ls -ltr | tail -n 1

파일이 너무 많으면 찾기를 세분화하십시오.


1
-l에 대한 옵션은 ls불필요한 것 같다. 그냥 -tr충분한 것 같다.
Acumenus

6
이것은 디렉토리별로 정렬 된 것으로
보이므로

1
파일 경로에 공간이있는 경우 다음을 수행하는 것이 좋습니다.find . -type f -print0 | xargs -0 ls -ltr | tail -n 1
정기 유지 관리

이것은 나를 위해 최신 파일을 찾지 못합니다.
K.-Michael Aye

1
파일 이름에 공백이 있으면 이것이 중단된다고 생각하십시오
waferthin

7

사람이 읽을 수있는 타임 스탬프가있는 최신 파일을 표시합니다.

find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1

결과는 다음과 같습니다.

2015-10-06 11:30: +0200 ./foo/bar.txt

더 많은 파일을 표시하려면 더 -n1높은 숫자로 바꾸십시오


5

나는 가장 최근에 수정 된 파일의 최상위 k 목록뿐만 아니라 항상 비슷한 것을 사용합니다. 큰 디렉토리 트리의 경우 정렬을 피하는 것이 훨씬 빠릅니다 . 가장 최근에 수정 된 파일이 최상위 1 개인 경우 :

find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()'

170 만 개의 파일이 포함 된 디렉토리에서 정렬을 사용하여 25.5s 솔루션에 비해 7.5 배 빠른 3.4s의 최신 파일을 얻습니다.


매우 시원합니다 : 방금 마지막 인쇄를 다음과 같이 교환했습니다.
Martin T.

@MartinT. : 좋아요, 천만에요. 사람들이 O (n) 방법을 사용할 수있을 때 물건을 정렬하는 본능을 가지고 있다는 것은 이상합니다 (O (n log n)). 이것은 정렬을 피하는 유일한 대답 인 것 같습니다. BTW, 내가 제안한 명령의 목표는 최신 파일의 경로를 찾는 것입니다. 쉘에서 명령의 별명을 지정하고 (예 lastfile:), 결과를 사용하여 원하는대로 (예 : ls -l $(lastfile .), 또는 open $(lastfile .)Mac에서) 수행 할 수 있습니다 .
Pierre D

아, 나는 정정했다 : 나는 아래에 또 다른 대답을 본다 (@marco). +1.
Pierre D

4

정렬 된 목록을 제공합니다.

find . -type f -ls 2>/dev/null | sort -M -k8,10 | head -n5

정렬 명령에 '-r'을 넣어 순서를 반대로 바꿉니다. 파일 이름 만 원하면 "awk '{print $ 11}'|" '| 전에 머리'


3

우분투 13에서 다음은 정렬을 반대로하고 '꼬리'대신 '머리'를 사용하여 작업을 줄임으로써 다소 빠릅니다. 트리에서 11 개의 최신 파일을 표시하려면

찾기 . 유형 f -printf '% T @ % p \ n'| 정렬 -n -r | 머리 -11 | 컷 -f2- -d ""| sed -e 's, ^. / ,,'| xargs ls -U -l

이것은 재정렬없이 완전한 ls 목록을 제공하고 'find'가 모든 파일 이름에 넣는 성가신 './'를 생략합니다.

또는 bash 함수로 :

treecent () {
  local numl
  if [[ 0 -eq $# ]] ; then
    numl=11   # Or whatever default you want.
  else
    numl=$1
  fi
  find . -type f -printf '%T@ %p\n' | sort -n -r | head -${numl} |  cut -f2- -d" " | sed -e 's,^\./,,' | xargs ls -U -l
}

여전히 대부분의 작업은 plundra의 독창적 인 솔루션으로 수행되었습니다. 고마워요 plundra.


3

나는 같은 문제에 직면했다. 최신 파일을 재귀 적으로 찾아야합니다. 찾기까지 약 50 분이 걸렸습니다.

다음은 좀 더 빠른 스크립트입니다.

#!/bin/sh

CURRENT_DIR='.'

zob () {
    FILE=$(ls -Art1 ${CURRENT_DIR} | tail -n 1)
    if [ ! -f ${FILE} ]; then
        CURRENT_DIR="${CURRENT_DIR}/${FILE}"
        zob
    fi
    echo $FILE
    exit
}
zob

디렉토리의 가장 최근에 수정 된 항목을 얻는 재귀 함수입니다. 이 항목이 디렉토리이면 함수를 재귀 적으로 호출하고이 디렉토리 등을 검색합니다.


3

다음과 같이 더 짧고 해석하기 쉬운 출력을 찾습니다.

find . -type f -printf '%TF %TT %p\n' | sort | tail -1

표준화 된 ISO 형식 날짜 시간의 고정 길이를 감안할 때 사전 사전 정렬은 괜찮으며 -n정렬 옵션이 필요하지 않습니다 .

타임 스탬프를 다시 제거하려면 다음을 사용할 수 있습니다.

find . -type f -printf '%TFT%TT %p\n' | sort | tail -1 | cut -f2- -d' '

2

stat각 파일에서 개별적으로 실행 하는 것이 느리다면 xargs속도를 높이는 데 사용할 수 있습니다 .

find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" " 

2

현재 디렉토리의 모든 디렉토리의 수정 시간을 각 디렉토리의 최신 파일로 재귀 적으로 변경합니다.

for dir in */; do find $dir -type f -printf '%T@ "%p"\n' | sort -n | tail -1 | cut -f2- -d" " | xargs -I {} touch -r {} $dir; done

1
dirs에 공백이 있으면 잘못 나옵니다. IFS를 설정하고 따옴표를 사용해야합니다. IFS = $ '\ n'; dir in $ (find ./ -type d); echo "$ dir"; "$ dir"찾기 -type f -printf '% T @ "% p"\ n'| 정렬 -n | 꼬리 -1 | 컷 -f2- -d ""| xargs -I {} touch -r {} "$ dir"; 끝난;
Andy Lee Robinson

2

이 간단한 cli도 작동합니다.

ls -1t | head -1

-1을 나열하려는 파일 수로 변경할 수 있습니다


10
아니요, 재귀 적이 지 않기 때문에 그렇지 않습니다.
arataj

1

위의 명령이 유용하다는 것을 알았지 만 제 경우에는 파일의 날짜와 시간을 볼 필요가 있었으며 이름에 공백이있는 여러 파일에 문제가있었습니다. 여기 내 작업 솔루션이 있습니다.

find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " | sed 's/.*/"&"/' | xargs ls -l

1

다음 명령은 Solaris에서 작동했습니다.

find . -name "*zip" -type f | xargs ls -ltr | tail -1 

1

멋지고 빠른 타임 스탬프와 함께 숨겨진 파일 무시

$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10

결과

파일 이름의 공백을 잘 처리합니다. 공백을 사용해서는 안됩니다!

2017.01.25 18h23 Wed ./indenting/Shifting blocks visually.mht
2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht
2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht
2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht

find링크를 따라 더 많은 맛이 있습니다.


1

지난 60 분 동안 수정 된 / target_directory 및 모든 해당 서브 디렉토리에서 파일을 검색하려면 다음을 수행하십시오.

$ find /target_directory -type f -mmin -60

가장 최근에 수정 된 파일을 찾으려면 업데이트 시간의 역순으로 정렬합니다 (즉, 가장 최근에 업데이트 된 파일이 먼저).

$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r

0

나는 이것을 선호한다. 더 짧다.

find . -type f -print0|xargs -0 ls -drt|tail -n 1

0

솔루션도 필요했기 때문에이 질문에 대한 pypi / github 패키지를 작성했습니다.

https://github.com/bucknerns/logtail

설치:

pip install logtail

사용법 : 꼬리가 변경된 파일

logtail <log dir> [<glob match: default=*.log>]

Usage2 : 편집기에서 최근에 변경된 파일을 엽니 다

editlatest <log dir> [<glob match: default=*.log>]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.