【问题标题】:rename multiple files with regular-expression使用正则表达式重命名多个文件
【发布时间】:2017-09-16 08:45:18
【问题描述】:

在一个文件夹中,我有一个文件结构,文件都有一个名称,其格式

name-randomstring.extension

例如

./dir1/aaa-5h34jk5hk.js
./dir2/bbb-5yh45uh9h.css
./dir3/ccc-uiero6tio.js
./dir3/ddd-7y8fygfre.css
. . .

使用 脚本,我想递归地重命名它们;所以要从每个文件中消除-randomstring

./dir1/aaa.js
./dir2/bbb.css
./dir3/ccc.js
./dir3/ddd.css
. . .

【问题讨论】:

  • @Tom:这不是重复的。该链接应仅表明可以将 sed 的语法与 rename 命令一起使用。
  • 你的意思是因为文件模式不完全一样,不是重复的吗?我不同意。
  • 该目录中还有其他目录吗?我的意思是你需要递归重命名吗?
  • 是的,需要递归重命名,使用 find 命令和管道?
  • 在这种情况下,stackoverflow.com/q/16541582/2088135 可能重复。

标签: bash bash


【解决方案1】:

您可以使用本机 bash 循环来执行此操作:

shopt -s globstar # enable ** for recursive expansion
for file in **/*{j,cs}; do
    # remove everything up to the last . to get extension
    ext=${file##*.}

    # remove everything after the last - and concat with extension
    new_name=${file%-*}$ext 

    # -- prevents weird filenames being interpreted as options
    mv -- "$file" "$new_name" 
done
shopt -u globstar # disable ** if you don't want it anymore e.g. in a script

【讨论】:

    【解决方案2】:

    如果您不介意使用 Perl,那么您可以做任何您喜欢的事情。

    例如重命名具有这种结构的所有文件:

    dir > find .
    .
    ./00_file.txt
    ./01_file.txt
    ./02_file.txt
    ./dir1
    ./dir1/00_file.txt
    ./dir1/01_file.txt
    ./dir1/02_file.txt
    ./dir2
    ./dir2/00_file.txt
    ./dir2/01_file.txt
    ./dir2/02_file.txt
    ./dir3
    ./dir3/00_file.txt
    ./dir3/01_file.txt
    ./dir3/02_file.txt   
    ./find.log
    

    然后将您的列表保存在一个文件中,例如:find.log 现在您可以使用 Perl

    dir > perl -lne '-f && ($old=$_) && s/file/ABCD/g && print "$old => $_"' find.log
    ./00_file.txt => ./00_ABCD.txt
    ./01_file.txt => ./01_ABCD.txt
    ./02_file.txt => ./02_ABCD.txt
    ./dir1/00_file.txt => ./dir1/00_ABCD.txt
    ./dir1/01_file.txt => ./dir1/01_ABCD.txt
    ./dir1/02_file.txt => ./dir1/02_ABCD.txt
    ./dir2/00_file.txt => ./dir2/00_ABCD.txt
    ./dir2/01_file.txt => ./dir2/01_ABCD.txt
    ./dir2/02_file.txt => ./dir2/02_ABCD.txt
    ./dir3/00_file.txt => ./dir3/00_ABCD.txt
    ./dir3/01_file.txt => ./dir3/01_ABCD.txt
    ./dir3/02_file.txt => ./dir3/02_ABCD.txt 
    

    它是如何工作的?

    1. 读取文件
    2. 只允许归档;不是目录或其他内容:-f
    3. 然后保存旧名称:($old=$_)
    4. 然后用:s///g operator 进行替换
    5. 最后将旧文件重命名为新文件$_

    注意我使用了print,你应该像这样使用rename

    dir > perl -lne '-f && ($old=$_) && s/file/ABCD/g && rename $old, $_' find.log
    dir > find .
    .
    ./00_ABCD.txt
    ./01_ABCD.txt
    ./02_ABCD.txt
    ./dir1
    ./dir1/00_ABCD.txt
    ./dir1/01_ABCD.txt
    ./dir1/02_ABCD.txt
    ./dir2
    ./dir2/00_ABCD.txt
    ./dir2/01_ABCD.txt
    ./dir2/02_ABCD.txt
    ./dir3
    ./dir3/00_ABCD.txt
    ./dir3/01_ABCD.txt
    ./dir3/02_ABCD.txt
    ./find.log 
    

    注意 因为find 返回所有文件和子目录的列表,使用这种技术 Perl 重命名所有文件!因此首先使用print 然后rename。你的模式可以是:-.*(?=\.)。事实上:

    s/-.*(?=\.)//g
    

    【讨论】:

      猜你喜欢
      • 2017-08-24
      • 2011-09-14
      • 2017-08-10
      • 2021-11-04
      • 2011-12-09
      • 2018-08-22
      • 2011-04-28
      相关资源
      最近更新 更多