如何重命名文件和替换字符?


11

我有一组:名称中包含(冒号)的文件。我需要:-(破折号)代替。

有没有一种简单的方法可以在脚本中执行此操作?

样本文件名: 2013-10-11:11:52:08_055456663_045585_.txt

Answers:


17

一个简单的1-liner应该可以做(假设Posix sh兼容的shell):

for f in *:*; do mv -v "$f" $(echo "$f" | tr ':' '-'); done

说明:

  • for ... in ...; do ...; done是一个循环

  • *:* 匹配当前目录:中名称相同的所有文件和目录

  • f 在循环中依次分配给每个这样的文件名

  • mv将其第一个参数重命名为第二个;-v(详细)要求它打印其功能;此选项特定于GNU-utils,因此在Linux上可用,但在Solaris上不可用

  • $(...) 在子外壳中执行代码并替换输出

  • echo 将其参数输出到标准输出

  • tr 读取标准输出并根据提供的地图翻译字符

如果您使用的是bash,则可以通过替换为来避免产生$()带有子进程(tr)的额外shell()。$(...)${f//:/-}


+1是一个简单的有效答案,尽管可以做更多解释。例如for f in... ...循环是一个循环遍历当前目录中需要匹配文件的所有文件的循环*:*。(匹配的dirs会发生什么?)。move命令是一个移动旧名称新名称,其中通过使用shell执行新名称$( subshell here )。tr会做什么,...
Hennes

@Hennes:这是超级用户 -我真的需要详细介绍这些细节吗?哦,好,您去...
sds

不。如果确实有需要,那么我就不会+1。而且我了解它的作用。我认为这对其他许多读者来说还是不错的。
Hennes

2
你可以替换$(echo "$f" | tr ':' '-')使用"${f//:/-}",避免子shell,管道和外部程序调用。我认为这是一种bashism,但是。看这里
evilsoup

@evilsoup确实;对于小的数据集,它并没有太大的区别(而且可能会有利于可读性),但是您会惊讶地发现,这样的数据累积起来有多快。我最近被它咬了。重写脚本,从而不再需要两个简单的字符串按摩命令,可以轻松地将执行时间减少90%或更多,这在大型数据集上可以转换为几分钟的运行时间。
CVn 2013年

6

正如我在另一篇文章中所述,该rename工具可以为您解决问题。您只需要键入“ rename s/:/-/ <files to rename> This”,即可在您最后命名的所有文件中用破折号替换每个冒号,即2013-10-*

这是我其他帖子的链接


1

我确信UNIX专业人士可以使用bash做到这一点,但这是我使用ruby的快速而肮脏的版本。

path_to_files = "/home/username/wrongnames/"
filenames = `ls #{path_to_files}`.split
filenames.each do |fn|
  `mv #{path_to_files + fn} #{path_to_files + fn.gsub(/:/, "-")}`
end

将path_to_files设置为您的错误命名文件的路径。将以上代码保存在名为rename.rb的文件中,然后:

username@machinename$ ruby rename.rb

@sds提供了更好的答案。我应该删除答案吗?我是stackoverflow的新手。
shupru

1
没有; 它仍然具有重大价值。:)
Blacklight Shining

2
但是,此答案有一些主要缺点,这些缺点可能是相关的,并且绝对值得了解。(它可能仍然有用,但请注意告急者和所有这些。)首先,当遇到其中带有空格(不只是经典的失败案例换行符)的文件名时,它看起来会严重损坏。另外,即使不是空格,您也应该在shell调用中引用文件名,以保护文件名中的其他任何特殊字符不被Shell处理(尽管我不知道Ruby的反引号运算符是如何工作的)。
CVn

1

如果只有一个或几个文件,则可以为您重命名:

  1. 将您要定位的文件名的模式存储为变量:p="201*"
  2. 存储要重命名的旧文件名old_name=$(ls | grep $p)
  3. 存储新文件名并替换必要的字符:

    new_name=$(ls | grep $p | sed 's/:/_/g')        # Using 'sed'
    
                OR
    
    new_name=$(ls | grep $p | tr ':' '_')           # Using 'tr'
    

奖金清理
  一。如果为了统一起见,您想将破折号(-)和冒号(:)替换为下划线(_),则可以执行以下操作:

    new_name=$(ls | grep $p | tr ':-' '_');

  b。如果您也希望最后一个下划线(恰好在之前.txt),请将new_name变量设置为:

    new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./')
  1. 现在根据需要重命名文件: mv $old_name $new_name

         注意:mv如果重命名操作中包含任何文件名,它将失败spaces。在这种情况下,请将适当的变量用引号引起来,例如:
mv "$old_name" $new_name OR mv $old_name "$new_name" OR mv "$old_name" "$new_name"


单线

1a: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | sed 's/:/_/g'); mv $old_name $new_name

1b: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':' '_'); mv $old_name $new_name

2: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':-' '_'); mv $old_name $new_name

3: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./'); mv $old_name $new_name

0

使用重命名器

$ renamer --find ":" --replace "-" *

我认为安装仅重命名文件的完整node.js环境有点太多。rename是在许多Linux发行版中预安装的工具。但是我认为对于Windows,此工具可能很棒。
noggerl 2013年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.