重命名目录及其子目录中的文件

问题描述 投票:0回答:2

我正在尝试用下划线 (

_
) 替换目录及其子目录的文件名中的特殊字符。

我有一个名为“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 find file-rename mv
2个回答
1
投票

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
    (无操作)标志来完成此操作。这将模拟重命名操作并显示生成的文件名而不实际重命名文件。

0
投票

你做了

-exec basename {}
大概是为了避免替换目录分隔符
/
,但是你正在丢失目录信息,所以不要。当保留路径不变时,我们只需要将
/
包含在普通字符类中:

…find . -type f | …
   mv "$FILE" "${FILE/[!0-9a-zA-Z.\/-]/_}"
© www.soinside.com 2019 - 2024. All rights reserved.