我正在尝试使用命令“mv”批量重命名文件夹及其各自的文件,但它不是很顺利,我希望将文件夹重命名为:
1/
2/
3/
等
在保留文件扩展名的同时,还应重命名每个文件夹中的文件。
1.png
2.gif
3.jpg
等
非常感谢你的帮助
答案 0 :(得分:2)
编辑:更好地使用函数而不是对同一脚本进行递归调用。
希望我得到所有角落案件。它以递归方式下降到目录中以处理深层嵌套的目录树。
警告:由于脚本注意不要覆盖现有文件,因此在某些极端情况下编号中可能会出现间隙 - 如果目录中存在文件0.txt
并且在该文件中处理了第一个文件目录是.txt
文件,它将被移动到1.txt
。如果处理的第一个文件是0.txt
,也会发生这种情况,因此运行脚本两次将更改编号,再次运行将更改它。
所以这是代码:
#!/bin/bash
handle_directory() {
local counter=0
for i in *; do
# if the file is a directory (but not a symlink),
# handle it before moving
if [ -d "$i" ] && ! [ -h "$i" ]; then
cd "$i"
handle_directory
cd ..
fi
# extract suffix
suffix="${i##*.}"
if [ "$suffix" != "$i" ]; then
extension=".$suffix"
else
# If there is no filename extension, the counter
# is the whole filename. Without this, we'd get
# 0.Makefile and suchlike.
extension=""
fi
# find a filename that isn't already taken
# this may lead to gaps in the numbering.
while dest="$counter$extension" && [ -e "$dest" ]; do
let ++counter
done
echo mv "$i" "$dest"
let ++counter
done
}
# if a parameter was given, go there to handle it.
# otherwise handle the local directory.
if ! [ -z "$1" ] && ! cd "$1"; then
echo "Could not chdir to directory $1"
exit -1
fi
handle_directory
一般的想法是深度优先搜索有问题的目录树。像任何树一样,目录树最好以递归方式处理,并且该函数基本归结为:遍历此目录中的所有内容,如果它们是目录,则下载并处理它,然后找到适当的文件名并重命名该事物是否它是一个目录。
使用的东西:
local counter=0 # declares a function-local variable counter and initializes it
# to 0. crucially, that it is local means that every invocation
# of handle_directory has its own counter.
[ -d "$i" ] # tests if "$i" is a directory
[ -h "$i" ] # tests if "$i" is a symlink
! [ ... ] # negates the test. ! [ -h "$i" ] is true if "$i" is NOT a symlink
"${i##*.}" # a bashism that cuts off the longest prefix that matches the pattern
[ -e "$dest" ] # tests if "$dest" exists
$1 # the first parameter with which the script is called
[ -z "$1" ] # tests if "$1" is an empty string
! cd "$1" # descends into the directory "$1". true if that failed.
阅读以便进一步理解的手册:
man test
man bash # that's the big one.
答案 1 :(得分:1)
是单级目录吗?或者你有子目录吗?
这样的东西?
<强>之前强>:
.
├── folderE
│ ├── conf.properties
│ ├── omg.avi
│ └── test-diff.diff
├── folder_a
│ ├── first.png
│ ├── main.jpg
│ └── second.gif
├── folder_d
│ ├── another.zip
│ └── one.mpeg
└── with space
└── file with spaces too.mov
<强>命令:强>
countDir=1
for dir in *; do
cd "$dir";
countFile=1
for file in *; do
mv "$file" $countFile.${file#*.}
((countFile++))
done
cd ..
mv "$dir" $countDir
((countDir++))
done
或者,在同一行中相同:
countDir=1; for dir in *; do cd "$dir"; countFile=1; for file in *; do mv "$file" $countFile.${file#*.}; ((countFile++)); done; cd ..; mv "$dir" $countDir; ((countDir++)); done
<强>后:强>
.
├── 1
│ ├── 1.properties
│ ├── 2.avi
│ └── 3.diff
├── 2
│ ├── 1.png
│ ├── 2.jpg
│ └── 3.gif
├── 3
│ ├── 1.zip
│ └── 2.mpeg
└── 4
└── 1.mov
重要提示:请注意,这只是一个快速而肮脏的解决方案,并且没有检查已经命名的文件/导演&#34; 1&#34; &#34; 2&#34;等