我正在尝试用下划线 (
_
) 替换目录及其子目录的文件名中的特殊字符。
我有一个名为“folder1”的文件夹,其中包含以下文件:
-rw-r--r-- 1 macair staff 0 Apr 13 16:19 #ababa.txt
-rw-r--r-- 1 macair staff 0 Apr 13 12:51 @babba.txt
drwxr-xr-x 3 macair staff 96 Apr 24 15:55 Folder2
-rwxr-xr-x 1 macair staff 379 Apr 25 11:17 myScript
-rw-r--r-- 1 macair staff 0 Apr 13 16:19 test1.txt
在“folder2”中,我有以下文件:
-rw-r--r-- 1 macair staff 0 Apr 24 15:55 #cdcda.txt
我尝试运行脚本来更改文件名,但更改仅反映在“folder1”中,而不反映在“folder2”中。
这是我使用的脚本:
#!/bin/bash
#find . -type f -exec grep -i "[^0-9a-z/.\/-\_]" {} \;
for FILE in $(find . -type f -exec basename {} \; | grep -i "[^0-9a-z\.\/_\-]")
do
echo $FILE
mv "$FILE" "${FILE/[!0-9a-zA-Z.-]/_}"
done
echo Done!!
但我收到以下错误:
mv:将#cdcda.txt 重命名为 _cdcda.txt:没有那个文件或目录
作为 Linux 的初学者,如果有任何改进上述代码的帮助或建议,我将不胜感激。
Linux 以提供强大而高效的实用程序而闻名,这些实用程序使用户能够以直接的方式执行常见任务,例如重命名文件,而无需 Bash 脚本。
话虽如此,你会在下面找到一个相关的例子:
find . -depth -type f -name '*[^0-9a-zA-Z\.\/_\-]*' -exec rename -n 's/[^0-9a-zA-Z\.\/_\-]/_/g' {} +
结果:
rename(./folder2/#cdcda.txt, ./folder2/_cdcda.txt)
rename(./@babba.txt, ./_babba.txt)
rename(./#ababa.txt, ./_ababa.txt)
备注:
depth
指定子目录将在其父目录之前被处理。type f
指定只搜索文件。exec rename
指定 find
将对每个符合搜索条件的文件执行 rename
命令。s/
指定替换操作。/_/
是用下划线替换任何匹配字符的替换字符串。g
修饰符表示全局,表示应替换所有出现的匹配字符。{}
是一个占位符,find
将替换为匹配搜索条件的每个文件的路径。+
指示 find
一次对尽可能多的文件执行 rename
命令,而不是一次一个。这可以通过减少多次调用rename
命令的开销来提高操作效率。警告:
-n
命令后使用 rename
(无操作)标志来完成此操作。这将模拟重命名操作并显示生成的文件名而不实际重命名文件。你做了
-exec basename {}
大概是为了避免替换目录分隔符/
,但是你正在丢失目录信息,所以不要。当保留路径不变时,我们只需要将/
包含在普通字符类中:
…find . -type f | …
mv "$FILE" "${FILE/[!0-9a-zA-Z.\/-]/_}"