단일 파일로 디렉터리를 평면화

단일 파일로 디렉터리를 평면화

나는 다음과 같은 디렉토리 구조를 가지고 있습니다

root_directory
--sub_a
----index.html
--sub_b
----index.html
--sub_c
----index.css
----index.html

이제 파일을 상위 디렉터리로 이동하고 상위 폴더 이름을 따서 이름을 바꾸고 싶지만 해당 파일이 하위 디렉터리에 있는 유일한 파일인 경우에만 가능합니다. 그러면 다음과 같이 디렉터리가 효과적으로 평면화됩니다.

root_directory
--sub_a.html
--sub_b.html
--sub_c
----index.css
----index.html

이를 달성하는 현명한 방법이 있습니까? 할 수는 있지만 find . -name 'index.html'디렉터리에 해당 파일이 아닌 다른 파일이 포함되어 있는지 추가로 확인하는 방법을 잘 모르겠습니다. 이러한 파일 목록이 있으면 위로 이동할 수 있지만( mv path/index.html ..) 어떤 방식으로든 폴더 이름을 재사용하여 이름을 바꾸는 것이 더 현명할 수 있습니다.

답변1

sub_x일반 파일만 포함하지만 하나 이상의 하위 디렉터리나 다른 유형의 파일 또는 기호 링크를 포함하는 디렉터리 와 같이 디렉터리 아래에 하위 디렉터리가 없다고 가정 sub_x하면 파일 이름을 상위 디렉터리로 바꾸라는 메시지가 표시됩니다. 삭제되었으니 주의하시기 바랍니다.

# !/bin/bash 

find /path/to/root_directory/ -type d -execdir bash -c '
    for file in "$1"/*; do
        [[ -f "$file" ]] && (( $((++filesCount)) > 1 )) && exit 1;
    done;
    ((filesCount==1)) && echo mv -v "$file" "${file%/*}.${file##*.}" && echo rm -r "$1"
' _ {} \; 2>/dev/null

테스트 실행 출력:

mv -v ./sub_b/index.html ./sub_b.html
rm -r ./sub_b
mv -v ./sub_a/index.html ./sub_a.html
rm -r ./sub_a

echo수행할 명령 mvrm명령의 실제 작업 에서 s를 제거합니다 . 결과:

root_directory
 ├── sub_a.html
 ├── sub_b.html
 └── sub_c
     ├── index.css
     └── index.html

find ... -type d -execdir bash -c '...' _ {} \;

find디렉토리 만 -d및 인라인 스크립트 실행bash -c '...' 이내에(이 작업의 사용법 -execdir) 찾은 모든 디렉토리에 대해.


for file in "$1"/*; do
    [[ -f "$file" ]] && (( $((++filesCount)) > 1 )) && exit 1;
done;

반환된 디렉터리 경로의 모든 파일을 반복하고, 파일 $1인지 확인한 다음 -f, 변수를 증가시키고, 해당 값이 1을 초과하는지(디렉토리에 최소 2개의 파일이 있음을 의미) 확인하고, 그렇다면 인라인 스크립트를 종료합니다. 및 find명령 처리를 계속하기 위해 다음 디렉터리를 읽습니다. exit처리 시간을 줄이기 위해 사용되며 해당 디렉터리의 파일은 해당 디렉터리(파일이 하나만 포함된 디렉터리)에 대한 기준을 충족하지 않기 때문에 계속 계산되지 않습니다.


((filesCount==1)) && mv -v "$file" "${file%/*}.${file##*.}" && rm -r "$1"

filesCount가 1인지 확인한 다음 파일 이름을 바꾸고 디렉터리를 삭제하면 사용법이 알려집니다 ${file%/*}.${file##*.}쉘 매개변수 확장.

관련 정보