상위 폴더와 같은 하위 폴더의 파일 이름을 바꾸고 중앙 폴더로 이동합니다.

상위 폴더와 같은 하위 폴더의 파일 이름을 바꾸고 중앙 폴더로 이동합니다.

상위 폴더 뒤에 특정 파일의 이름을 바꾼 다음 중앙 폴더로 이동해야 하는 문제가 있습니다. 이를 수행할 수 있는 방법이 있습니까? Synology NAS에서 실행하고 싶습니다.

Root
 |-Subf1
 |  |-File.txt
 |  |-File.doc
 |  |-Subf1subf1
 |  |  |-File.xml
 |  |  |-File.xls
 |  |-Subf1subf2
 |  |  |-File.pptx
 |  |  |-File.docx
 |
 |-Subf2
 |  |-File.txt
 |  |-File.doc
 |  |-Subf2subf1
 |  |  |-File.xml
 |  |  |-File.xls

결과는 다음과 같습니다.

Root
 |-Subf1
 |  |-Subf1.txt
 |  |-Subf1.doc
 |  |-Subf1.xml
 |  |-Subf1.xls
 |  |-Subf1.pptx
 |  |-Subf1.docx
 |
 |-Subf2
 |  |-Subf2.txt
 |  |-Subf2.doc
 |  |-Subf2.xml
 |  |-Subf2.xls

확장자가 모두 다르기 때문에 파일을 덮어쓰는 데 문제가 없습니다.

답변1

#! /bin/bash

shopt -s globstar  #enabled for '**' to match all files &directories recursively
#shopt -s dotglob  #uncomment to enable to match on hidden files/directories too

cd /path/to/directory/Root
for pathname in ./**/*; do
    [[ -f "$pathname" ]] && echo mv -v -- "$pathname" "${pathname%%/*}/${pathname%%/*}.${pathname##*.}";
done

##then remove remained empty directories
for pathname in ./**/*; do
    [[ -d "$pathname" && -z "$(ls -A -- "$pathname")" ]] && rm -r -- "$pathname";
done
  • [[ -f "$pathname" ]]파일 $pathname인지 확인해보세요f
  • ${pathname%%/*}: 사용쉘 매개변수 확장, 매개변수에서 가장 긴 접미사를 제거합니다 pathname. 첫 번째 슬래시 문자 앞의 모든 내용을 잘라냅니다 /.
  • ${pathname##*.}": 동일하지만 인수에서 가장 긴 접두사를 제거하고 pathname마지막 점 문자까지 모든 것을 자릅니다 ..
  • [[ -d "$pathname" ]]디렉터리 $pathname인지 확인하세요.d
  • ... && -z "$(ls -A -- "$pathname")"그런 다음 기본 이름이 다음과 같은지 확인하십시오.pathname 이것은 디렉토리입니다. 비어 있습니까?.

echo결과가 만족스러우면 삭제하세요.

답변2

POSIX적으로:

cd Root &&
  LC_ALL=C find . \
    -name '.?*' -prune -o \
      -path './*/*/*' \
      -prune \
      -name '*.*' \
      -type f \
      -exec sh -c '
        ret=0
        for file do
          ext=${file##*.}
          sub=${file%/*/*}
          subname=${sub##*/}
          echo mv -i "$file" "$sub/$subname.$ext" || ret=$?
        done
        exit "$ret"' {} +

echo(만족스러우면 삭제)

그런 다음 다음 명령을 사용하여 빈 디렉터리를 삭제할 수 있습니다.

find . -depth -type d -exec rmdir {} + 2> /dev/null

또는 find비표준 -empty합계를 지원하는 경우 -delete:

find . -type d -empty -delete

( -delete힌트 -depth).

관련 정보