유닉스 / 리눅스 수정 날짜별로 찾기 및 정렬


138

find가장 최근에 수정 한 결과를 정렬 하는 간단한 방법은 무엇입니까?

다음은 현재 find사용중인 것입니다 (PHP에서 쉘 이스케이프를하고 있으므로 변수에 대한 추론입니다).

find '$dir' -name '$str'\* -print | head -10

가장 최근에 수정 한 순서대로 검색하려면 어떻게해야합니까? (참고로 검색 후 '정렬'하는 것이 아니라 가장 최근에 수정 된 내용을 기준으로 결과를 찾습니다.)


github.com/shadkam/recentmost 는 원하는 것을 할 것입니다 – 그러나 그것을 만들 필요가 있습니다
user3392225

답변:


153

이것을 사용하십시오 :

find . -printf "%T@ %Tc %p\n" | sort -n

printf의 인수 man find:

  • %Tk:에서 지정한 형식의 파일의 마지막 수정 시간입니다 k.

  • @: 1970 년 1 월 1 일부터 00:00 GMT (소수점)

  • c: 로케일 날짜 및 시간 (11 월 04 일 12:02:33 EST 1989).

  • %p: 파일 이름.


5
+1 매우 유용합니다. 첫 번째 답은 읽기 / 유용한 날짜 출력으로 찾은 것입니다.
Jake N

시간이 숫자 순으로 (따라서 항상 적절하게 정렬 가능), 시간이 주어지기 때문에 가장 신뢰할 수 있고 매우 간단합니다!
Aquarius Power

1
내에서 최근 파일을 찾기위한이 별칭이 ~/.zshrc: fr () { find ./ -iname "*"$@"*" -printf "%T@ %Td-%Tb-%TY %Tk:%TM %p\n" | sort -n | cut -d " " -f 2- | grep -i "$@" ; }그것은 재귀 (명령에 전달 된 첫 번째 인수의 패턴이 들어있는 모든 파일을 찾아 fr <pattern>)을 마지막으로 가장 최근의로 정렬됩니다.
joelostblom

대단해 !!! 심볼릭 링크와 함께 사용하려면find -L ...
Varun Chandak

1
당신은 사용할 수 있습니다 ssed초 소수 부분 없애 및 STIL @PeterMortensen을 가리 켰을 때, ISO8601를 사용 :find . -type f -printf "%TY-%Tm-%TdT%TT %p\n" | sort -r | ssed -R 's/^([^.]+)\.\d+ (.*)$/\1 \2/'
루도빅 Kuty

83

가장 쉬운 방법은 glob 한정자 덕분에 zsh를 사용하는 것 입니다.

print -lr -- $dir/**/$str*(om[1,10])

GNU find가 있으면 파일 수정 시간을 인쇄하고 그 순서대로 정렬하십시오.

find -type f -printf '%T@ %p\0' |
sort -zk 1nr |
sed -z 's/^[^ ]* //' | tr '\0' '\n' | head -n 10

GNU find가 있지만 다른 GNU 유틸리티는없는 경우 널 대신 구분 기호로 줄 바꾸기를 사용하십시오. 줄 바꿈이 포함 된 파일 이름은 지원되지 않습니다.

find -type f -printf '%T@ %p\n' |
sort -k 1nr |
sed 's/^[^ ]* //' | head -n 10

Perl이있는 경우 (여기서는 파일 이름에 줄 바꿈이 없다고 가정합니다) :

find . -type f -print |
perl -l -ne '
    $_{$_} = -M;  # store file age (mtime - now)
    END {
        $,="\n";
        @sorted = sort {$_{$a} <=> $_{$b}} keys %_;  # sort by increasing age
        print @sorted[0..9];
    }'

파이썬이있는 경우 (파일 이름에 줄 바꿈이 없다고 가정) :

find . -type f -print |
python -c 'import os, sys; times = {}
for f in sys.stdin.readlines(): f = f[0:-1]; times[f] = os.stat(f).st_mtime
for f in (sorted(times.iterkeys(), key=lambda f:times[f], reverse=True))[:10]: print f'

PHP에서 동일한 작업을 수행하는 방법이 있을지 모르지만 잘 모르겠습니다.

POSIX 도구로만 작업하려면 다소 복잡합니다. 참조 반복적으로 수정 날짜별로 정렬 파일을 나열하는 방법 (사용할 수없는 stat 명령을!) (첫 번째 10 retatining하는 것은 쉬운 부분이다).


find버전에 가장 오래된 파일이 표시되고에 -r옵션을 추가해야 한다고 생각합니다 sort.
Quentin Pradet

내 sed는 -z 옵션이 없다고 말합니다.
Kef Schecter

@KefSchecter 그런 다음 줄 바꾸기를 구분 기호로 사용하지만 파일 이름에서 줄 바꿈을 지원하지 않습니다.
Gilles

위의 내용은 python2입니다. python3 만 가지고 있다면 약간의 변화가 있습니다 : python3 -c 'import os, sys; sys.stdin.readlines ()에서 f의 횟수 = {} : f = f [0 : -1]; times [f] = os.stat (f) .st_m f in (sorted (times.keys (), key = lamfda f : times [f], reverse = True)) [: 10] : print (f); '
닐 맥길

40

PHP 나 Python이 필요하지 않습니다 . ls :

man ls:
-t     sort by modification time
-r,    reverse order while sorting (--reverse )
-1     list one file per line

find /wherever/your/files/hide -type f -exec ls -1rt "{}" +;

command *가 실패 상태 (즉, Argument list too long )로 종료되면 find를 사용하여 반복 할 수 있습니다. 다음에서 해석 : 새로운 프로세스에 대한 최대 인수 길이

  • find . -print0|xargs -0 command (찾기가 "-exec +"를 구현하지 않지만 "-print0"을 알고있는 경우 속도를 최적화합니다)
  • find . -print|xargs command (인수에 공백이없는 경우)

인수의 주요 부분이 길고, 절대적이거나 상대적인 경로로 구성된 경우 조치를 디렉토리로 이동하십시오. cd /directory/with/long/path; command *또 다른 빠른 수정 사항은 더 적은 인수를 일치시키는 것입니다.command [a-e]*; command [f-m]*; ...


1
파일이 많으면 ls에서 '인수 목록이 너무 깁니다'로 실패합니다.
occulus

1
사실이지만 질문은 "어떻게 간단한 찾기를합니까?"라고 생각합니다.
Ярослав Рахматуллин

2
ls는 xargs가 이해할 수있는 방식으로 파일 이름을 인용하지 않습니다 (-0 옵션이없고 다양한 인용 스타일이 부적절합니다)
Tobu

10

당신은 ls 만 필요 합니다

find /wherever/your/files/hide -type f -exec ls -1rt "{}" +;위에서 언급 한대로 할 수 있습니다 .

또는

ls -1rt `find /wherever/your/file/hides -type f`

2
파일이 많으면 ls에서 '인수 목록이 너무 깁니다'로 실패합니다. 아마도 xargs를 사용하기 위해 요리를 하시겠습니까?
occulus

2
그러나 여러 번 xargs호출 ls하면 정렬이 중단됩니다.
Aaron D. Marasco

이름에 공백이있는 파일은 실패합니다. 어떤 충고?
user74094

이 답변을 우연히 발견했으며 비슷한 상황에서 정확히 필요한 것입니다. 질문 : +;끝에는 무엇을합니까? 없이 동일한 결과를 제공하는 것 ;그러나 그것이 없이는 작동하지 않습니다 +?
RocketNuts

이것은 "ls -1rt`find…`"사용에 대한 부분을 제외하고 8 개월 전에 게시 된 다른 답변과 동일합니다.
Clément

7

user195696의 답변 확장 :

find . -type f -printf "%T@\t%Tc %6k KiB %p\n" | sort -n | cut -f 2-

각 파일에 대해 먼저 숫자 타임 스탬프 (정렬, 정렬, 탭 \t), 사람이 읽을 수있는 타임 스탬프, 파일 크기 조정 (불행히도 find' -printf메이 바이트, 킬키 바이트 만'), 파일 이름이 통로.

그런 다음 sort -n첫 번째 숫자 필드를 기준으로 정렬합니다.

그런 다음 cut사용자에게 관심이없는 첫 번째 숫자 필드를 제거합니다. (두 번째 필드를 앞으로 인쇄합니다.) 기본 필드 구분 기호는 \t또는 표입니다.

출력 예 :

Thu 06 Feb 2014 04:49:14 PM EST     64 KiB ./057_h2_f7_10/h2_f7_10.class
Fri 07 Feb 2014 02:08:30 AM EST 7962976 KiB ./056_h2_f7_400/h2__rh_4e-4.mph
Fri 07 Feb 2014 02:23:24 AM EST 7962976 KiB ./056_h2_f7_400/h2_f7_400_out_Model.mph
Fri 07 Feb 2014 02:23:24 AM EST      0 KiB ./056_h2_f7_400/h2_f7_400_out.mph.status
Fri 07 Feb 2014 02:23:24 AM EST     64 KiB ./056_h2_f7_400/1579678.out
Fri 07 Feb 2014 03:47:31 AM EST 8132224 KiB ./057_h2_f7_10/h2__rh_1e-5.mph
Fri 07 Feb 2014 04:00:49 AM EST 8132224 KiB ./057_h2_f7_10/h2_f7_10_out_Model.mph
Fri 07 Feb 2014 04:00:49 AM EST      0 KiB ./057_h2_f7_10/h2_f7_10_out.mph.status
Fri 07 Feb 2014 04:00:49 AM EST     64 KiB ./057_h2_f7_10/1579679.out
Fri 07 Feb 2014 09:47:18 AM EST   9280 KiB ./056_h2_f7_400/h2__rh_4e-4.mat
Fri 07 Feb 2014 10:51:23 AM EST   9728 KiB ./018_bidomain/h2_plain__rh_1e-5.mat
Fri 07 Feb 2014 10:58:33 AM EST   9568 KiB ./057_h2_f7_10/h2__rh_1e-5.mat
Fri 07 Feb 2014 05:05:38 PM EST     64 KiB ./058_h2_f7_stationary/h2_f7_stationary.java
Fri 07 Feb 2014 06:06:29 PM EST     32 KiB ./058_h2_f7_stationary/slurm.slurm
Sat 08 Feb 2014 03:42:07 AM EST      0 KiB ./058_h2_f7_stationary/1581061.err
Sat 08 Feb 2014 03:42:14 AM EST     64 KiB ./058_h2_f7_stationary/h2_f7_stationary.class
Sat 08 Feb 2014 03:58:28 AM EST  70016 KiB ./058_h2_f7_stationary/h2s__rh_1e-5.mph
Sat 08 Feb 2014 04:12:40 AM EST  70304 KiB ./058_h2_f7_stationary/h2s__rh_4e-4.mph
Sat 08 Feb 2014 04:12:53 AM EST  70304 KiB ./058_h2_f7_stationary/h2_f7_stationary_out_Model.mph
Sat 08 Feb 2014 04:12:53 AM EST      0 KiB ./058_h2_f7_stationary/h2_f7_stationary_out.mph.status
Sat 08 Feb 2014 04:12:53 AM EST     32 KiB ./058_h2_f7_stationary/1581061.out
Mon 10 Feb 2014 11:40:54 AM EST    224 KiB ./058_h2_f7_stationary/h2s__rh_4e-4.mat
Mon 10 Feb 2014 11:42:32 AM EST    224 KiB ./058_h2_f7_stationary/h2s__rh_1e-5.mat
Mon 10 Feb 2014 11:50:08 AM EST     32 KiB ./plot_grid.m

필자는 파일 크기를 6 자로 설정했습니다. 더 길게 만들면 파일의 크기를 시각적으로 구분하기가 어렵 기 때문입니다. 이 방법으로 1e6 KiB보다 큰 파일은 제거됩니다 .1 문자는 1-9GB, 2 문자는 10-99GB 등입니다.


편집 : 여기에 다른 버전이 있습니다 ( find . -printf "%Tc"MinGW / MSYS에서 충돌하기 때문에 ).

find . -type f -printf "%T@\t%p\n" | sort -n | cut -f 2- | xargs -I{} ls -Glath --si {}

다음과 같은 출력 제공 :

-rw-r--r-- 1 es 23K Jul 10  2010 ./laptop_0000071.jpg
-rw-r--r-- 1 es 43M Jul 29 19:19 ./work.xcf
-rw-r--r-- 1 es 87K Jul 29 20:11 ./patent_lamps/US Patent 274427 Maxim Lamp Holder.jpg
-rw-r--r-- 1 es 151K Jul 29 20:12 ./patent_lamps/Edison screw-in socket.png
-rw-r--r-- 1 es 50K Jul 29 20:13 ./patent_lamps/1157 Lamp.jpg
-rw-r--r-- 1 es 38K Jul 29 20:14 ./patent_lamps/US06919684-20050719-D00001.png

어디:

  • -I{}발생을 {}인수로 대체 하고 개행은 이제 인수 구분 기호입니다 (위 파일 이름의 공백에 유의하십시오).

  • ls -G 그룹 이름 인쇄 (공간 낭비)를 억제합니다.

  • ls -h --si사람이 읽을 수있는 파일 크기를 생성합니다 (보다 정확함 --si).

  • ls -t 시간에 따라 정렬되는데, 여기서는 관련이 없지만, 내가 일반적으로 사용하는 것입니다.


1
참고 : 대신 파일 크기 별로 정렬하려면 위 명령 중 하나 에서 T@by s를 바꾸십시오 .
Evgeni Sergeev

3

@ user195696의 답변에 대한 OS X 변형 :

  1. 타임 스탬프 포함 :

    find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r
    
  2. 타임 스탬프없이 :

    find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r | awk -F' ' '{ print substr($0, length($1) + 2) }'
    

2

나는 이것이 Mac OS X (그리고 다른 Unixen에서도 작동 할 수있는 일반)에서 작업을 수행한다는 것을 알았습니다.

find . -type f -ls | awk '{print $(NF-3), $(NF-2), $(NF-1), $NF}' | sort

2
슬프게도, 이것은 크로아티아어 설정에서 현지화 된 월 이름을 인쇄하여 정렬을 잘못합니다.
Ivan Vučica

user195696의 답변 은 크로아티아어 설정 및 기타에 적용됩니다.
Peter Mortensen

1

find선택이 매우 간단한 경우 선택하지 않고 다음을 사용할 수 있습니다 ls.

ls -1 *.cc # -r -t optional

1

시험:

find '$dir' -name '$str'\* -print | xargs ls -tl | head -10

그러나 -mmin/ -mtime및로 데이터를 필터링하는 것도 유용합니다 -type.


1

사용하다:

find . -type f -mtime 0 -printf "[%TD %TI:%TM%Tp] %s %p\n" | sort -n | awk '{
    hum[1024**4]="TB"; hum[1024**3]="GB"; hum[1024**2]="MB"; hum[1024]="KB"; hum[0]="B";
    for (x=1024**4; x>=1024; x/=1024){
    if ($3>=x) { printf $1" "$2"\t%7.2f %s\t%s\n",$3/x,hum[x],$4;break }
    }}';

이 명령은 수정 된 날짜별로 파일을 정렬합니다.

그리고 다음과 같이 표시하십시오.

[12/05/13 03:10PM] 1.75 MB ./file.text
[12/06/13 11:52PM] 2.90 MB ./file2.mp4
[12/07/13 04:11PM] 4.88 MB ./file3.mp4
[12/07/13 09:17PM] 4.74 MB ./test.apk

파일 이름에서 공백을 처리하기 위해이 sript를 개선했습니다. superuser.com/a/777007/134532
jan

1

FreeBSD (OS X)와 Linux 모두에서 작동하는 간단한 솔루션이 있습니다.

find . -type f -exec ls -t {} +

이것은 완벽하게 작동합니다. 정답이거나 최소한 더 높은 등급이어야합니다!
디지털 토스트

0

find출력 순서를 수정하는 옵션 이 없다고 생각 합니다. -mtime그리고 -mmin당신은 자신 있다고해야 할 것이다 - 당신이 특정 시간 창 내에서 수정 된 파일로 결과를 제한하게됩니다 만, 출력은 정렬되지 않습니다. GNU find에는 -printf무엇보다도 발견 된 각 파일의 수정 시간을 인쇄 할 수 있는 옵션이 있습니다 (형식 문자열 %t또는 %Tk). find출력을 원하는대로 정렬하는 데 도움이 될 수 있습니다 .


0

스크립트가 파일 이름의 공백을 올바르게 처리하여 Akashs 답변을 개선했습니다.

find . -type f -mtime 0 -printf ";[%TD %TI:%TM%Tp];%s;%p\n" | sort -n | awk -F ";" '{
    hum[1024**4]="TB"; hum[1024**3]="GB"; hum[1024**2]="MB"; hum[1024]="KB"; hum[0]="B";
    for (x=1024**4; x>=1024; x/=1024){
    if ($3>=x) { printf $1" "$2"\t%7.2f %s\t%s\n",$3/x,hum[x],$4;break }
    }}';

0

시간 단위로 모든 PNG 파일을 주문하려는 경우 $PWD:

이 간단한 한 줄은에 정규 표현식의 모든 유연성을 제공 find하고에 ls.

find $PWD -name "*.png" -print0 | xargs -0 ls -laht | less

0

stat이 방식으로 BSD 및 Linux (POSIX가 아닌)에서 사용할 수 있습니다 .

$ stat -f "%m%t%N" /[the dir]/* | sort -rn | cut -f2-

수를 제한하려는 경우 :

$ stat -f "%m%t%N" /[the dir]/* | sort -rn | head -[the number] | cut -f2-

0

sort | head날짜별로 깨끗하고 강력한 방법이 있습니다.

사용하여 ls -l고급 인쇄에 대한

find . ! -type d -printf "%T@ %p\0" |
    sort -zrn |
    head -zn 10 |
    sed -z 's/^[0-9.]\+ //' |
    xargs -0 ls -lt

함수 로서 :

findByDate() {
    local humansize=''
    [ "$1" = "-h" ] && humansize='h' && shift
    find . ${2:-! -type d} -printf "%T@ %p\0" |
        sort -zrn |
        head -zn ${1:--0} |
        sed -z 's/^[0-9.]\+ //' |
        xargs -0 ls -dlt${humansize}
}

이것은 하나 또는 두 개의 인수로 실행하거나 다음과 같이하지 않아도 실행될 수 있습니다.

Usage: findByDate [-h] [lines] [find options]

견본:

findByDate

날짜별로 정렬 된 모든 비 디렉토리를 나열합니다 . 참고 :

큰 파일 시스템 트리에서도 xargs 이미 정렬 된 목록을 받으면 ls여러 번 실행해야 하더라도 파일 순서는 그대로 유지 됩니다.

findByDate -h 12

사람이 읽을 수있는 형태로 인쇄 된 크기로 날짜별로 정렬 된 최근 12 개가 아닌 최근 디렉토리를 나열

findByDate 42 '-type l'

42 개의 최근 심볼릭 링크가 더 나열됩니다

findByDate -0 '( -type l -o -type b -o -type s -o -type c )'

모든 심볼릭 링크, 블록 장치, 소켓 및 문자 장치를 날짜별로 정렬하여 나열합니다.

역순

교체 headtail와의 스위치를 변경 sort하고 ls:

findByDate() {
    local humansize=''
    [ "$1" = "-h" ] && humansize='h' && shift
    find . ${2:-! -type d} -printf "%T@ %p\0" |
        sort -zn |
        tail -zn ${1:-+0} |
        sed -z 's/^[0-9.]\+ //' |
        xargs -0 ls -dltr${humansize}
}

동일한 기능, 동일한 사용법 :

Usage: findByDate [-h] [lines] [find options]

-1

각 항목의 전체 경로를 얻으려면 다음과 같이 적어 두십시오.

 find FIND_ROOT -maxdepth 1 -type f -printf "%T@ %p\n" | sort -nr | head -10 | cut -d ' ' -f 2

여기서 정렬 기준 (날짜), 날짜 별 정렬을위한 'sort -nr' , 상위 10 개의 결과를 나열하려면 -10 을, -d ''-f 2정렬하려면
-printf "% T @ % p \ n" 각 라인의 타임 스탬프



cut -d ' ' -f 2파일 이름에 공백이 있으면 중단됩니다.
F. Hauri

-3

간단한 해결책이 있습니다.

cd디렉토리 사용하기

find . -iname "*" -ls


1
이것은 수정 된 날짜별로 정렬되지 않습니다.
DavidPostill
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.