폴더 타임스탬프를 최신 파일로 재귀적으로 변경하는 방법은 무엇입니까?

폴더 타임스탬프를 최신 파일로 재귀적으로 변경하는 방법은 무엇입니까?

해당 폴더에 있는 파일의 최신 타임스탬프를 기반으로 폴더의 타임스탬프를 재귀적으로 변경하는 방법을 아는 사람이 있는지 궁금합니다.

예를 들어:

jon@UbuntuPanther:/media/media/MP3s/Foo Fighters/(1997-05-20) 색상 및 모양 $ ls -alF
합계 55220
drwxr-xr-x 2 JonJon4096 2010-08-30 12:34 ./
drwxr-xr-x 11 Jon Jon4096 2010-08-30 12:34 ../
-rw-r--r-- 1 jon jon 1694044 2010-04-18 00:51 Spitfire-Doll.mp3
-rw-r--r-- 1 jon jon 3151170 2010-04-18 00:51 스핏파이어만큼 충분한 공간.mp3
-rw-r--r-- 1 jon jon 5004289 2010-04-18 00:52 Spitfire-Everlong.mp3
-rw-r--r-- 1 jon jon 5803125 2010-04-18 00:51 Spitfire-February Star.mp3
-rw-r--r-- 1 jon jon 4994903 2010-04-18 00:51 푸 파이터스 - 안녕, 조니 파크! .mp3
-rw-r--r-- 1 jon jon 4649556 2010-04-18 00:52 스핏파이어-몽키 렌치.mp3
-rw-r--r-- 1 jon jon 5216923 2010-04-18 00:51 Spitfire-My Hero.mp3
-rw-r--r-- 1 jon jon 4294291 2010-04-18 00:52 Foo Fighters - My Poor Brain.mp3
-rw-r--r-- 1 jon jon 6778011 2010-04-18 00:52 Spitfire- New Way Home.mp3
-rw-r--r-- 1 jon jon 2956287 2010-04-18 00:51 Foo Fighters - Goodbye.mp3
-rw-r--r-- 1 jon jon 2730072 2010-04-18 00:51 Foo Fighters - Up in Arms.mp3
-rw-r--r-- 1 jon jon 6086821 2010-04-18 00:51 Foo Fighters - Follow You.mp3
-rw-r--r-- 1 jon jon 3033660 2010-04-18 00:52 Foo Fighters - Wind Up.mp3

"(1997-05-20) The Color and The Shape" 폴더의 타임스탬프는 2010-04-18 00:52로 설정됩니다.

답변1

현재 시간(또는 ) touch -r대신 다른 파일의 타임스탬프를 사용할 수 있습니다 .touch --reference=FILE

여기에는 두 가지 해결책이 있습니다. 각 솔루션에서 첫 번째 명령은 디렉터리의 수정 시간을 바로 아래에 있는 최신 파일의 수정 시간으로 변경하고, 두 번째 명령은 전체 디렉터리 트리를 반복적으로 살펴봅니다. cd '.../(1997-05-20) The Colour and The Shape'명령을 실행하기 전에 디렉토리( )로 변경하십시오.

zsh에서( D점 파일을 무시하기 위해 제거됨):

touch -r *(Dom[1]) .
touch -r **/*(Dom[1]) .

Linux에서(또는 더 일반적으로 GNU find를 사용하여):

touch -r "$(find -mindepth 1 -maxdepth 1 -printf '%T+=%p\n' |
            sort |tail -n 1 | cut -d= -f2-)" .
touch -r "$(find -mindepth 1 -printf '%T+=%p\n' |
            sort |tail -n 1 | cut -d= -f2-)" .

그러나 이는 파일 이름에 개행 문자가 없다고 가정합니다.

답변2

현재 디렉터리와 하위 디렉터리의 모든 타임스탬프를 업데이트하려는 경우현재 시간으로:

find . -exec touch {} \;

답변3

이는 "재귀적"이 아니며 폴더의 모든 타임스탬프만 변경합니다. 이것이 의미하는 바라면 두 단계가 있습니다.

stat -c '%Y' filename타임스탬프를 출력 filename하고 stat -c '%Y %n' *폴더에 있는 모든 파일의 타임스탬프와 파일 이름을 출력하므로 현재 폴더에서 가장 최근에 수정된 파일의 파일 이름을 찾습니다.

mostrecent="`stat -c '%Y %n' * | sort -n | tail -n1 | cut -d ' ' -f '2-'`"

다시 생각해 보세요.방법폴더에서 가장 높은 타임스탬프를 얻는 더 쉬운 방법:

mostrecent="`ls -t | head -n1`"

그런 다음 폴더의 모든 파일이 이 파일과 동일한 타임스탬프를 갖도록 변경하려고 합니다. 와 동일한 수정 타임스탬프를 갖도록 touch -r foo bar변경되므로 폴더의 모든 파일이 가장 최근에 수정된 파일과 동일한 수정 타임스탬프를 갖도록 변경됩니다.barfoo

touch -r "$mostrecent" *

따라서 한 줄은 다음과 같습니다.

touch -r "`ls -t | head -n1`" *

답변4

@Gilles zsh 명령을 사용하여 하위 폴더에서 작동하도록 개선했지만 **/*(FDod) 부분에서는 zsh가 매우 비효율적인 것 같습니다.

# Don't do this
for d in **/*(FDod); do touch -r "$d"/*(Dom[1]) -- "$d"; done

따옴표를 사용하면 공백과 탭이 포함된 디렉터리 항목이 올바르게 작동할 수 있습니다. FD는 od로 시작하는 디렉토리를 포함하여 비어 있지 않은 디렉토리를 찾도록 합니다.깊이 우선상위 폴더 타임스탬프가 올바르게 업데이트되도록 합니다.

테스트하는 동안 **/*(FDod)의 성능과 메모리 공간이 미친 수준(단지 650,000개의 폴더에 대해 1.4GB 이상)이라는 사실을 발견했으며 폴더를 터치하기 전에 전체 내용을 읽었습니다. 검색/읽기로 교체한 후 속도가 빨라지고 메모리를 소비하지 않으며 거의 ​​즉시 시작되었습니다.

#! /usr/bin/env zsh
# Do this instead
find "$@" -depth -type d ! -empty -print0 |while IFS= read -r -d ''; do
    touch -r "$REPLY"/*(Dom[1]) "$REPLY"
done

스크립트에서 실행하지 않는 경우 "$@"를 실행하려는 폴더로 바꾸세요.

관련 정보