我遇到一个问题,我需要在父文件夹之后重命名某些文件,然后将它们移动到中央文件夹。有没有办法做到这一点?我想在 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%%/*}
: 使用shell 参数扩展,从参数中删除最长的后缀pathname
。剪切第一个斜线字符之前的所有内容/
。${pathname##*.}"
:相同,但是这会从参数中删除最长的前缀pathname
;剪切所有内容直到最后一个点.
字符。[[ -d "$pathname" ]]
检查是否$pathname
是一个d
目录... && -z "$(ls -A -- "$pathname")"
然后检查基名是否pathname
这是一个目录,是否为空。
echo
当您对结果满意时删除。
答案2
POSIXly:
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
)。