디렉터리를 계층 구조로 재구성

디렉터리를 계층 구조로 재구성

수천 개의 폴더가 있는 다음과 같은 유형의 폴더 구조가 있습니다.

폴더 이름 자체가 다른 이름 등을 가지고 있습니다.

.test
.test.subfolder
.test.subfolder.subsubfolder

.folder
.folder.one
.folder.two
.folder.one.one

.test내가 달성해야 할 것은 다음과 같습니다. 예를 들어 폴더의 이름을 from 으로 바꾼 test다음 .test.subfolder폴더가 폴더 없이 폴더 안에 .subfolder있도록 이동한 다음 해당 폴더 내부 와 내부에 있도록 하고 싶습니다 .test..test.subfolder.subsubfoldersubfoldertestsubsubfoldertest/subfolder

폴더가 많기 때문에 재귀가 필요합니다. 폴더의 파일은 그대로 유지되어야 한다는 점을 기억하세요.

이것이 가능한가?

답변1

이 bash 스크립트는 필요한 작업을 수행합니다.

#!/bin/bash
for dir in .*/ ; do
    [[ $dir == ./ || $dir == ../ ]] && continue  # Skip the special dirs
    new=${dir#.}                                 # Remove the dot at the beginning
    new=./${new//.//}                            # Replace dots with slashes, prepend ./
    new=${new%/}                                 # Remove the trainling slash
    mkdir -p ${new%/*}                           # Create the parent dir
    mv "$dir" "$new"                             # Move the dir to destination
done

답변2

네, 가능합니다. 당신이 해야 할 일은 경로에 있는 모든 파일 이름을 읽고 공백, 점 등을 고려해야 한다는 것입니다. 이 작업을 효율적으로 수행하려면 다음 스레드를 사용할 수 있습니다.하위 폴더에서 특정 확장자를 가진 모든 파일에 대해 우아한 방식으로 작업을 수행하는 방법은 무엇입니까?

이제 경로 이름의 파일을 읽었으면 규칙을 만들어야 합니다.

예를 들어 다음 구조를 고려해 보겠습니다.

 .test
  .test.subfolder
   .test.subfolder.subsubfolder

당신이 원하는 것은 각 파일 이름에서 sub라는 단어의 발생 횟수를 세는 것입니다. 따라서 개수가 0이면 상위 폴더이고, 개수가 1이면 첫 번째 수준 하위 폴더이고, 개수가 3이면 두 번째 수준 하위 폴더입니다. 귀하가 제공한 구조에서 파생됩니다)

따라서 가능한 의사코드는 다음과 같습니다:

  if(filename contains(".test"))
  {
   searchCount("sub");
   if(count ==0)
   parent();
   else if(count ==1)
   1stLevelChild();//and so on
  }

이제 얻은 결과에 따라 이동 명령을 사용하여 파일을 적절한 폴더로 이동할 수 있습니다.

답변3

zsh에서는 매우 쉽습니다. 감사합니다.zmv. 와일드카드는 .*파일 이름을 사전순으로 확장하므로 부모가 될 디렉터리의 이름은 항상 하위 디렉터리보다 먼저 변경됩니다. 즉, test이름을 바꿀 때 이미 존재합니다..test.subfolder

zmv '.(*)' "${1//./\/}"

관련 정보