현재 디렉터리의 마지막 수정된 하위 디렉터리로 전환

현재 디렉터리의 마지막 수정된 하위 디렉터리로 전환

주기적으로 여러 디렉터리에 여러 파일을 생성하는 애플리케이션이 있는데 생성된 최신 파일, 즉 가장 최근 디렉터리(생성 또는 업데이트)에 생성된 파일을 확인해야 합니다. 파일 이름은 모든 디렉터리에서 동일하게 유지되므로 디렉터리를 마지막으로 수정된 하위 디렉터리로 변경하는 간단한 스크립트만 필요합니다.

[업데이트] 대부분의 답변을 살펴보면서 디렉터리 이름이 동적이므로(일부 사용자 입력 및 타임스탬프에 따라) dir[1, 2, 3]과 같은 디렉터리 패턴을 가정할 수 없다는 점을 명확히 해야 한다고 생각했습니다. 또는 이와 유사한

답변1

이를 위해 복잡한 배관이 필요하지 않습니다. 게다가, 아무것도 할 필요가 없습니다 find. 모든 파일이 어디에 있는지 이미 알고 있지만, 그 중 어떤 파일이 최신인지는 알 수 없습니다. 이것은 다루기가 쉽습니다.

이를 입증하기 위해 여기에 작은 테스트가 있습니다.

mkdir ./dir1 ./dir2 ./dir3

for d in 1 2 3
do  touch ./dir$d/samefile
    sleep 1
done

그러면 테스트 세트가 생성됩니다. 자, 어느 것이 최신입니까?

set -- ./dir[123]/samefile
while [ -e "$2" ]
do  [ "$1" -nt "$2" ] && 
    set -- "$@" "$1"
shift; done
printf %s\\n "$@"

그게 나에게 말해 줄 것이다.

산출

./dir3/samefile

touch작업 순서를 마음대로 바꿀 수 있습니다. 그러면 올바른 정보가 제공됩니다. 필요한 것은 다음과 같은 함수 내의 작은 쉘 루프뿐입니다.

newd() { ${2:+:} return 1
    while [ -e "$2" ] && [ -e "$1" ]
    do  [ "$1" -nt "$2" ] && 
        set -- "$@" "$1"
    shift; done
    ${2+false} cd "${1%/*}"
}

이는 데모와 약간 다르기 때문에 인수가 2개 미만이거나 인수가 실제 경로 이름이 아닌 경우 안정적으로 실패합니다.

이제 다음과 같이 호출할 수 있습니다.

newd ./path/to/file1 ./path/to/file2

...등등 - 원하는 만큼 많은 인수를 가질 수 있습니다.

또는 내 테스트 사례에서는 다음과 같습니다.

newd ./dir[123]/samefile ; pwd

산출

/home/mikeserv/test/dir3

답변2

수행하려는 작업과 파일 구조에 따라 다음과 같은 다른 가능성이 있을 수 있습니다.

ls -1tq /dir/*/readme.txt | head -n 1

/dir/의 하위 디렉터리에 있는 최신 readme.txt의 전체 이름을 반환합니다(비재귀적으로).

파일 이름의 일부가 아닌 경로의 일부로 *를 사용하는 것은 일반적으로 알려져 있지 않으며 언급할 가치가 있다고 생각했습니다.

file=$( ls -1tq /dir/*/readme.txt | head -n 1 )
cd $( dirname "$file" )

답변3

더 많은 이식성을 위해 다음을 사용할 수 있습니다 perl.

$ perl -MList::Util=reduce -le '
    BEGIN { $dir = "." }
    opendir DIR,$dir;
    print shift @{(reduce {$a->[1] > $b->[1] ? $a : $b}
                   map {[$_,(stat($_))[9]]}
                   grep { -d and !/^..?$/ }
                   readdir DIR)}
'
.Skype

$dir검색하려는 디렉터리로 변경하세요 .

어떻게 작동하나요?

  • readdirdir 핸들에 있는 모든 파일 및 디렉터리 목록을 반환합니다.opendir
  • grep { -d and !/^..?$/ }.: 모든 디렉터리, 건너뛰기 및 디렉터리를 가져옵니다 ...
  • map {[$_,(stat($_))[9]]}: 요소가 배열 참조이고 두 요소가 있는 배열을 만듭니다.
    • 첫 번째는 디렉토리 이름입니다.
    • 두 번째는 수정 시간입니다.
  • reduce {$a->[1] > $b->[1] ? $a : $b: max 함수와 마찬가지로 배열의 각 요소를 수정 시간인 두 번째 요소와 비교합니다.
  • @{...}배열을 역참조하고 shift첫 번째 요소인 디렉터리 이름을 가져옵니다.

답변4

man find짧은 대답: "시간" 옵션을 살펴보세요 . 그러면 파일을 찾은 다음 -printf옵션을 사용하여 사용할 수 있는 파일 경로를 표시합니다.cd <path>


find현재 디렉터리와 그 하위 디렉터리에서 마지막으로 접근한 파일(지난 24시간 이내)의 DIR을 사용 하고 추출하는 방법

lastAccDir="$(find 2>/dev/null .-type f -atime 1 -printf "%a~%h\n" | sort -r | head -n 1 | cut -d~ -f2)"

또는 줄 연속과 동일(가독성이 더 높음)

마지막 디렉토리 = "$(
2>/dev/null을 찾으세요. -type f \ -atime 1 -printf "%a~%h\n" \
 |정렬-r\
 |헤드-n 1\
 |cut-d~-f2
)"

(지난 24시간) 이로 -atime 1인해 결과가 비어 있을 수 있습니다.

test ! -z "$lastAccDir" && cd "$lastAccDir"
그런 다음 비어 있지 않은 결과를 확인하고 비어 있지 않으면 디렉토리로 이동하십시오.

관련 정보