![폴더 구조 병합](https://rvso.com/image/36020/%ED%8F%B4%EB%8D%94%20%EA%B5%AC%EC%A1%B0%20%EB%B3%91%ED%95%A9.png)
다음과 같은 폴더 구조가 있습니다.
├── 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에서 이를 수행하는 방법을 아시나요? 감사해요!
편집하다: 글렌 잭맨이 제안한 답변을 실행하면 다음과 같은 결과를 얻습니다.
첫 번째 수준 폴더에는 두 개의 밑줄이 있습니다. 이것을 피하는 방법이나 밑줄 하나만 사용하도록 이름을 바꾸는 방법에 대한 아이디어가 있습니까? 감사해요.
답변1
find */ -type f -exec bash -c 'file=${1#./}; echo mv "$file" "${file//\//_}"' _ '{}' \;
echo
만족스러우면 제거하세요 . 작동하는 것입니다. echo'ed 명령이 따옴표를 표시하지 않는다는 점에 대해 걱정하지 마십시오. 스크립트는 공백이 있는 파일을 적절하게 처리합니다.
현재 비어 있는 하위 디렉터리를 제거하려면 다음을 수행하세요.
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