UNIX 쉘 스크립팅: 파일을 한 디렉토리 위로 재귀적으로 이동하는 방법은 무엇입니까?

UNIX 쉘 스크립팅: 파일을 한 디렉토리 위로 재귀적으로 이동하는 방법은 무엇입니까?

다음과 같은 디렉토리 구조로 배열된 많은 수의 작은 파일 f가 있습니다.

/A/B/C/f

A 수준에는 11개의 디렉터리가 있고, 각 디렉터리에는 B 수준에 약 100개의 디렉터리가 있고, 각 수준에는 C 수준에 약 30개의 디렉터리가 있으며, 각 디렉터리에는 하나의 파일 f가 있습니다.

모든 파일을 한 수준 위로 이동하려면 어떻게 해야 하나요? 예를 들어, 다음 파일 세트가 주어지면...

/A/B/C/f1
/A/B/C/f2
/A/B/C/f3
/A/B/C/f4

/A/B/디렉토리 에 f1부터 f4까지 4개의 파일이 포함되기를 원합니다 . C 디렉터리를 제거할 필요는 없습니다.

find, xargs및 과 관련된 문제가 해결되기를 바랍니다 whatnot. 어떤 아이디어가 있나요?

건배,

제임스

답변1

GNU find(Linux에서 발견됨) 또는 다음을 지원하는 다른 find를 사용하면 매우 간단합니다 -execdir.

find A -type f -execdir mv -i {} .. \;

표준 find:

find A -type f -exec sh -c 'mv -i "$1" "${1%/*}/.."' sh {} \;

zsh를 사용하면:

zmv -Q -o-i 'A/(**/)*/(*)(.)' 'A/$1$2'

디렉터리 구조가 항상 동일한 중첩 수준을 갖는 경우 재귀 순회가 필요하지 않습니다(단, 빈 디렉터리를 먼저 제거).

for x in */*; do; echo mv -i "$x"/*/* "$x"/..; done

답변2

해당 파일 세트에 대해 다음을 수행합니다.

$ cd /A/B/C/
$ mv ./* ../

하지만 귀하의 문제는 좀 더 복잡할 것으로 예상됩니다. 이에 대해 답변할 수 없습니다. 귀하의 디렉토리 구조가 어떤지 잘 모르겠습니다... 명확히 설명해 주시겠습니까?

답변3

내 첫 번째 추측은

$ find A -type f -exec mv {} .. \;  

지정하지 않는 한 -depth괜찮습니다. 나는 그것을 시도하지 않았으므로 커밋하기 전에 먼저 테스트하십시오.

답변4

리프 디렉터리에 있는 파일만 이동하려는 경우(즉, 하위 디렉터리가 포함된 경우 /A/B/file이동 하고 싶지 않은 경우) 다음과 같은 몇 가지 방법이 있습니다./AB

둘 다 이것을 요구합니다

leaf ()
{
    find $1 -depth -type d | sed 'h; :b; $b; N; /^\(.*\)\/.*\n\1$/ { g; bb }; $ {x; b}; P; D'
}
shopt -s nullglob

이것은 작동합니다 :

leaf A | while read -r dir
do
    for file in "$dir"/*
    do
        parent=${dir%/*}
        if [[ -e "$parent/${file##*/}" ]]
        then
            echo "not moved: $file"
        else
            mv "$file" "$parent"
        fi
    done
done

이는 더 빠르지만 빈 소스 디렉터리를 좋아하지 않습니다.

leaf A | while read -r dir
do
    mv -n "${dir}"/* "${dir%/*}"
    remains=$(echo "$dir"/*)
    [[ -n "$remains" ]] && echo "not moved: $remains"
done

관련 정보