상위 폴더 뒤에 특정 파일의 이름을 바꾼 다음 중앙 폴더로 이동해야 하는 문제가 있습니다. 이를 수행할 수 있는 방법이 있습니까? 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
).