폴더의 모든 파일을 같은 이름의 하위 디렉터리로 어떻게 이동할 수 있나요?

폴더의 모든 파일을 같은 이름의 하위 디렉터리로 어떻게 이동할 수 있나요?

디렉토리에 여러 개의 파일이 있다고 가정해 보겠습니다.

filename-1.ext1
filename-1.ext2
filename-1.ext3
filename-2.ext1
filename-2.ext2
filename-2.ext3
filename-3.ext1
filename-3.ext2
filename-3.ext3

그런 다음 파일과 동일한 이름(파일 이름은 있지만 확장자는 없음)을 사용하여 동일한 디렉토리에 하위 디렉토리를 만들고 다음과 같이 이동하고 싶습니다.

filename-1
├──filename-1.ext1
├──filename-1.ext2
└──filename-1.ext3
filename-2
├──filename-2.ext1
├──filename-2.ext2
└──filename-2.ext3
filename-3
├──filename-3.ext1
├──filename-3.ext2
└──filename-3.ext3

이 목표를 달성하는 가장 효율적인 방법은 무엇입니까?

편집: ext1, ext2, ext3은 .foo, .bar, .top, .coffee 등과 같은 세 가지 다른 파일 이름을 의미합니다. 파일명이 비슷한 것은 아닙니다.

답변1

를 사용하고 있으므로 zsh다음과 같이 수행할 수 있습니다.

for name (*.ext<->(.)) mkdir -p -- $name:r && mv -- $name $name:r 

또는 더 친숙한 긴 루프 형식을 사용하세요 for.

for name in *.ext<->(.); do
    mkdir -p -- $name:r &&
    mv -- $name $name:r
done

*.ext<->이는 임의의 숫자에 대한 패턴과 일치하는 모든 일반 파일을 반복합니다 . 이는 일반 파일만 일치하도록 강제하는 glob 한정자입니다 <->. 점이 포함된 일반 파일의 파일 이름과 일치시키려면 (.)전체 패턴을 로 변경하십시오. *.*(.)나중에 파일 확장자를 제거하려면 점이 있어야 합니다. 느슨한 패턴보다는 더 엄격한 패턴을 사용하려면 다음과 같은 것을 사용하세요 filename-<->.ext<->(.). 이 패턴을 사용하려면 문자열로 시작하는 이름을 일치시키려는지 알아야 합니다 filename-.

확장은 $name:r와 동일한 값을 생성 $name하지만 확장은 제외됩니다(즉, 값의 "루트"만).

우리는 이를 사용하여 --두 옵션 모두에 옵션의 끝을 알리고 mkdir대시 mv로 시작하는 이름이 옵션으로 오인되는 것을 방지합니다.

답변2

그리고 zmv:

autoload -Uz zmv # best in ~/.zshrc
mkmv() { mkdir -p -- $2:h && mv -- "$@"; }

zmv -P mkmv -n '(*).ext<->(#q.)' '$1/$f'

(행복하면 삭제 -n).

이렇게 하면 zmv건전성 검사의 이점을 누릴 수 있습니다.

답변3

forbash 및 zsh 셸과 호환되는 루프를 사용하세요 .

for file in *.*; do
  [ -f "$file" ] &&
    mkdir -p -- "${file%.*}" &&
    mv -- "$file" "${file%.*}/"
done
  • -p파일이 존재하는지 확인하는 옵션이 mkdir오류를 발생시키지 않습니다.
  • %.*파일 이름에서 확장자를 제거하십시오.

답변4

GNU Parallel 사용(이제 막 깨닫기 시작한 도구의 강력함):

ls | parallel 'mkdir -p {.}; mv -i {} {.}'

parallel이것은 어떤 식으로든 CPU에 국한되지 않기 때문에 속도 이점은 없을 것이라고 생각 하지만 다른 솔루션보다 여전히 짧습니다.

이는 파일 이름의 패턴에 의존하지 않습니다.

관련 정보