我想删除“。”在我的文件夹和子文件夹的名称中。
我有名为“Archive.1”的文件夹; “Archive.2”(等),其中有名为“Document.1”等的文件夹。(等...),其中有名为“Document.1”等的文件夹。我想删除所有“.”。并有“Archive1”和“Document1”内部。
我有一个脚本的开头:
for f in *.mp4; do fn=`echo $f|sed 's/\.//g'`; mv "$f" "$fn"; done
但它只浏览我所在的文件夹。
你能帮助我吗?
提前致谢。
答案1
您可能想要使用find
,它(默认情况下)递归地搜索整个子树。
find -depth -type d -name '*.*' |
while read f
do
dn=`dirname "$f"`
bn=`basename "$f"`
mv "$dn/$bn" "$dn/${bn//.}"
done
该find
命令表示匹配名称中包含.
.该-depth
选项使其执行后序遍历在当前目录树上,即检查该目录本身之前的每个目录的内容,因此包含其他匹配目录(例如“ a.b/c.d
”)的匹配目录将输出为匹配项后后代的匹配(因此,“ a.b/c.d
”后跟“ a.b
”)。如果没有这个,循环可能会失败,因为find
会生成整个列表,而不知道或关心部分路径可能会中途更改;该循环仅作用于预编译列表,将执行“ a.b
” ->“ ab
”,然后尝试执行“ a.b/c.d
”->“ a.b/cd
”。后序遍历可以解决这样的问题。
在 Bash 中处理带有空格的文件名总是很痛苦,因为它倾向于将它们视为参数分隔符。上面的方法使用read
内置函数解决了这个问题,它仅将换行符视为分隔符。
由于我们只想操作每个目录的名称,而不是其整个路径名,因此我们将其分为部分前最后一个斜杠(“dirname”)和实际文件名(“basename”)并仅对基本名称进行操作。
此外,模式替换可以轻松处理转换,而无需借助外部过滤器。一般形式是${parameter/pattern/string}
,与 相比,它应该看起来很熟悉sed
。然而,在这里,pattern
以另一个斜杠开头用于指示所有匹配项都应该被替换,就像/g
在 中一样sed
。另外,由于string
是空的,所以前面的斜杠可以省略。
不完全确定您为什么要尝试匹配*.mp4
。您是否只查找.mp4
其中包含文件的路径?如果是这样,那么事情就有点复杂了。我们需要首先生成此类文件的路径名列表,然后从中过滤出目录路径名列表,并确保以正确的顺序对它们进行操作。