플랫 폴더 구조

플랫 폴더 구조

다음과 같은 폴더 구조가 있습니다.

├── foo1
│   ├── bar1.txt
│   └── bar2.txt
├── foo2
│   ├── bar3.txt
│   └── bar4 with a space.txt
└── foo3
    └── qux1
        ├── bar5.txt
        └── bar6.txt

각 폴더 수준 사이에 밑줄을 사용하여 평면화하고 싶습니다.

├── foo1_bar1.txt
├── foo1_bar2.txt
├── foo2_bar3.txt
├── foo2_bar4 with a space.txt
├── foo3_qux1.bar6.txt
└── foo3_qux1_bar5.txt

주위를 둘러보았지만 작동하는 해결책을 찾지 못했습니다. 주로 내 문제에는 두 가지 특징이 있기 때문입니다. 루트 폴더 내에 여러 폴더 수준이 있을 수 있고 일부 파일에 공백이 있을 수 있습니다.

Bash에서 이것을 달성하는 방법을 아시나요? 감사해요!

편집하다:Glenn Jackman이 제안한 답변을 실행하면 다음과 같은 결과를 얻습니다.

여기에 이미지 설명을 입력하세요.

첫 번째 수준 폴더에는 두 개의 밑줄이 있습니다. 이것을 피하는 방법이나 이름을 바꾸어 밑줄로 표시하는 방법에 대해 알고 계시나요? 감사해요.

답변1

find */ -type f -exec bash -c 'file=${1#./}; echo mv "$file" "${file//\//_}"' _ '{}' \;

echo작업에 만족하면 제거하십시오. echo 명령이 따옴표를 표시하지 않는 것에 대해 걱정하지 마십시오. 스크립트는 공백이 있는 파일을 올바르게 처리합니다.

현재 비어 있는 하위 디렉터리를 삭제하려면 다음을 수행하세요.

find */ -depth -type d -exec echo rmdir '{}' \; 

답변2

Perl을 사용하여 이름 바꾸기:

find . -depth -type f -exec rename 's@(?<!\.)/@_@g' -- {} \;

산출

$ find -type f
./foo2_bar4 whit a space.txt
./foo3_qux1_bar6.txt
./foo2_bar3.txt
./foo3_qux1_bar5.txt
./foo1_bar2.txt
./foo1_bar1.txt

노트

  • 나는 하나를 사용부정적으로 되돌아보기 (?<!\.)첫 번째 건 건드리지 마세요./
  • 디렉토리를 비워 두겠습니다. 자유롭게 사용하세요.

    find . -depth -type d -exec rm {} \;

경고하다이 작업을 수행할 수도 있고 수행하지 못할 수도 있는 같은 이름의 다른 도구가 있으므로 주의하세요.

다음 명령을 실행하면 ( GNU)

$ file "$(readlink -f "$(type -p rename)")"

이런 결과가 나왔어요

.../rename: Perl script, ASCII text executable

다음은 포함되지 않습니다:

ELF

그렇다면 이것이 올바른 도구인 것 같습니다 =)

그렇지 않은 경우 이를 기본값으로 설정하고(일반적으로 이미 적용되어 있음) Debian다음과 같이 파생시킵니다 Ubuntu.

$ sudo update-alternatives --set rename /path/to/rename

(명령어의 경로로 바꿉니다 /path/to/rename.perl's rename


이 명령이 없으면 패키지 관리자를 검색하여 설치하거나수동으로 수행


마지막으로 이 도구는 원래 Perl의 아버지인 Larry Wall이 작성했습니다.

답변3

그리고pax...

pax -Xrwls '|/|_|g' */ "$PWD"

그러면 현재 디렉터리에 해당 하위 디렉터리의 모든 파일에 대한 하드 링크가 생성되고 다음 명령을 사용하여 결과를 확인하고 모든 하위 디렉터리를 삭제할 수 _있습니다 ./

rm -rf */

...결과가 마음에 드는지 확인한 후.

답변4

다음 명령을 사용해 볼 수 있습니다.

$ find -type f -exec bash -c 'mv $0 $(echo $0|sed "s/\//_/2")' {} \;

위 명령은 파일을 이동하고 디렉터리는 그대로 유지되며 나중에 삭제할 수 있습니다.

$ ls
foo1_bar1.txt  foo1_bar2.txt  foo2_bar3.txt  foo2_bar4.txt  foo3_bar5.txt  foo3_bar6.txt

관련 정보