首页 > 解决方案 > 如何使用 perl-rename 替换 . 使用 _ 在 linux 上递归,扩展除外

问题描述

我正在尝试以递归方式重命名一些文件和文件夹以格式化名称,并认为find并且perl-rename可能是它的工具。我已经设法找到了我想要运行的大部分命令,但对于最后两个:

这样./my.directory/my.file.extension就变成了./my_directory/my_file.extension

对于第二个任务,我什至没有命令。

对于第一个任务,我有以下命令: find . -type d -depth -exec perl-rename -n "s/([^^])\./_/g" {} + which renames ./the_expanse/Season 1/The.Expanse.S01E01.1080p.WEB-DL.DD5.1.H264-RARBG ./the_expanse/Season 1/Th_Expans_S01E0_1080_WEB-D_DD__H264-RARBG,所以它不起作用,因为 an 之前的每个单词字符.都被吃掉了。

如果改为键入 : find . -type d -depth -exec perl-rename -n "s/\./_/g" {} +,我重命名./the_expanse/Season 1/The.Expanse.S01E01.1080p.WEB-DL.DD5.1.H264-RARBG_/the_expanse/Season 1/The_Expanse_S01E01_1080p_WEB-DL_DD5_1_H264-RARBGwhich 也不起作用,因为当前目录被替换为_.

如果有人能给我一个解决方案:

标签: linuxcommandrename

解决方案


首先处理目录.

# find all directories and remove the './' part of each and save to a file
$ find -type d  | perl -lpe  's@^(\./|\.)@@g' > list-all-dir
# 
# dry run
# just print the result without actual renaming 
$ perl -lne '($old=$_) && s/\./_/g && print' list-all-dir
#
# if it looked fine, rename them
$ perl -lne '($old=$_) && s/\./_/g && rename($old,$_)' list-all-dir
 

这部分s/\./_/g用于匹配每个.并将其替换为_


第二次处理文件扩展名,重命名文件扩展名.除外.

# find all *.txt file and save or your match
$ find -type f -name \*.txt  | perl -lpe  's@^(\./|\.)@@g' > list-all-file
#
# dry run
$ perl -lne '($old=$_) && s/(?:(?!\.txt$)\.)+/_/g && print ' list-all-file
#
# if it looked fine, rename them
$ perl -lne '($old=$_) && s/(?:(?!\.txt$)\.)+/_/g && rename($old,$_) ' list-all-file

这部分(?:(?!\.txt$)\.)+用于匹配文件扩展名之前的.最后一个除外。.


笔记

我在这里使用过.txt,你应该用你的匹配替换它。第二代码将像这样重命名输入:

/one.one/one.one/one.file.txt
/two.two/two.two/one.file.txt
/three.three/three.three/one.file.txt

到这样的输出:

/one_one/one_one/one_file.txt
/two_two/two_two/one_file.txt
/three_three/three_three/one_file.txt

您可以在此处使用在线正则表达式匹配对其进行测试。


推荐阅读