다음과 같은 구조를 가진 대규모 n-레벨 디렉터리가 있습니다.
root
|
subdir1
|
sub_subdir1
|
....(n-2 levels).....
|
file1
|
subdir2
|
sub_subdir2
|
....(n-2 levels).....
|
file2
모든 레벨 1이 되도록 디렉토리를 평면화하고 싶습니다.하위 디렉토리포함하다문서. 또한 레벨 2를 (n-1)로 제거하고 싶습니다.하위 하위 디렉터리파일이 포함되어 있지 않기 때문입니다. 하위 디렉터리의 이름은 모두 다릅니다.
원하는 결과
root
|
subdir1
|
file1
|
subdir2
|
file2
방법을 설명하는 게시물을 많이 찾았습니다.단조롭게 하다디렉토리에 있지만 제어된 방식으로 이를 수행하는 방법은 설명하지 않습니다.
- 평탄화할 수준을 지정하여
- 또는 루트 디렉터리의 모든 하위 디렉터리에 대해 이 작업을 반복적으로 수행합니다.
답변1
zsh 사용:
cd /root
for subdir in subdir*
do
mv "$subdir"/**/*(.) "$subdir"
rm -r "$subdir"/*(/)
done
이것:
- "/root" 디렉토리를 변경하십시오(귀하의 예에서)
- 이름이 지정된 각 하위 디렉터리를 반복합니다
subdir*
(예: subdir1 및 subdir1 일치). - 이 하위 디렉터리에 있는 일치하는(예상되지만 모두 일치하는) 파일을 이 하위 디렉터리로 이동합니다. 이는 zsh의
**
재귀 globbing 기능을 사용하고 glob 한정자로 한정됩니다.*(.)
즉, 이 디렉토리의 모든 항목은 일반 파일입니다. - 파일을 이동한 후 해당 하위 디렉터리 아래의 각 하위 디렉터리를 반복적으로 삭제합니다. 이는
*(/)
일치하는 디렉터리 항목을 나타내는 zsh glob 한정자를 다시 사용합니다.
답변2
Bash에서 다음을 수행합니다.
shopt -s dotglob
for d in root/*/
do
find "$d" -type f -exec mv -i -t "$d" {} +
find "$d" -mindepth 1 -type d -delete
done
root
도트 파일을 포함하여 " " 안의 모든 내용을 살펴봅니다 . 도트 파일을 볼 필요가 없으면 무시하세요 shopt -s dotglob
. 경고: 추가하지 마세요..*
또는 명령.root/.*
for
/
Jeff가 제안한 것처럼 마지막에 있는 glob()은 하위 디렉터리만 제공하므로 모든 하위 디렉터리를 테스트할 필요가 없습니다(예: 를 사용하여).root/*/
if
모든하위 디렉토리에서 root
해당 하위 디렉터리와 그 아래의 모든 파일을 찾아 해당 하위 디렉터리로 이동합니다. 파일을 덮어쓰는 것을 방지하는 데 사용됩니다 (예를 들어 Distributed라는 이름의 파일이 -i
여러 개 있는 경우 ). "대화형"을 의미하며 기존 파일을 덮어써야 하는지 묻습니다. 참고하시기 바랍니다file1
subdir1
-i
가능한당신이 "예"라고 대답하더라도 이것을 거부하십시오. 귀하의 버전이 mv
이 옵션을 지원하지 않는 경우 -t
명령을 mv
다음으로 바꾸십시오.
find "$d" -type f -exec mv -i {} "$d" ';'
그런 다음 최상위 하위 디렉터리 아래의 모든 하위 디렉터리를 삭제합니다. find
파일이 이동되지 않은 경우 이( ... )는 실패합니다.-delete
이 부분은 영감을 받아 만들어졌습니다.데로베르의 답변 도착하다 중첩된 디렉터리 평면화.