用终端替换文件名中的所有冒号


12

用EXT4格式化的硬盘上有GB的音乐。我想将这些文件移动到FAT格式的HDD分区。但是,我无法移动大部分文件,因为它们的名称中带有“:”(例如,歌剧的“ Act 2:.....”)。是否可以通过命令行将我的所有文件从“ XXXX:XXXX”重命名为“ XXXX-XXXX”?

Answers:


25

如果所有文件都在一个目录中,请尝试:

rename 's|:|-|g' *

(如果需要,可以将*更改为更具限制性的内容)

如果目录树中有许多文件,请从树的底部尝试:

find . -name "*:*" -exec rename 's|:|-|g' {} \;

您可以在该选项-n之后rename立即添加该选项,以使它告诉您在没有实际操作的情况下将要执行的操作。这可以帮助您避免意外踩到其他文件或其他不良情况...


1
单目录解决方案可以工作,但如果目录本身的名称中带有:s,则嵌套解决方案将无效。这是因为在find .子目录名称的输出中,其内容之前。因此,如果您/1:/2:首先有一个文件,/1:/它将被重命名为/1-/。现在您不能重命名/1:/2:为,/1-/2-因为/1:/2:它不存在。
S Prasanth

1
对于目录:find . -type d -readable -writable -exec rename 's|:|-|g' {} \;然后是文件:find . -type f -readable -writable -exec rename 's|:|-|g' {} \;

@Christopher如果在目录的名称中有两个级别的目录,则命令将失败。例如:/ 1:/ 2:/,其中2:也是目录。当然,如果在Ryan的情况下不是这种情况,那么它将起作用。
S Prasanth

对于多个级别的子目录,请使用:for i in {1..20}; do find . -maxdepth $i -mindepth $i -name "*:*" -exec rename 's|:|-|g' {} \;; done。将20更改为目录的最大深度。结构体。不一定要精确-可以更大。如果设置为非常大的数字,则将花费一些时间。
S Prasanth

0

我现在不在我的linux机器上,所以我只能提供大概的信息。

Linux有一个称为的命令行实用程序rename,可与其他输入,正则表达式或正则表达式一起使用。您应该能够在文件上使用它以及诸如“ s /:/-/”之类的正则表达式来实现所需的重命名。

为了安全起见,请进行小批量测试和/或使用模拟程序进行首次测试(重命名具有一个标志,该标志仅提供文件的旧名称和新名称,而无需实际重命名-请先使用该名称进行验证)


0

这是python中的解决方案,用于处理文件不一定位于同一目录中的情况。

import os
torename = []
rootdir = "The main directory"
logfile = "Path to log file" #Eg: logfile = "/home/prasanth/renamelog"
for (path, dirs, files) in os.walk(rootdir):
    for dirname in dirs:
        if ':' in dirname:
            torename.append(os.path.join(path, dirname))
    for filename in files:
        if ':' in filename:
            torename.append(os.path.join(path, filename))

print "No of files/dirs to rename =", len(torename)
a = raw_input("Continue? (y/n) ")
if a == 'y':
    torename.reverse()
    for oldname in torename:
        directory, filename = os.path.split(oldname)
        newname = os.path.join(directory, filename.replace(':', '-'))
        command = 'mv %s %s > /dev/null' % (repr(oldname), repr(newname))
        os.system(command)
        f = open(logfile, 'a')
        f.write(oldname + '\n')
        f.close()
else:
    print "Aborted."
  1. 将此保存到文件(例如)rename.py。
  2. 更改rootdir所考虑的最外面的目录(使用完整路径名称以/无速记或ENV变量,如允许〜)。无需在特殊字符前加上\-例如,如果最外层目录是/.../我的硬盘,则rootdir = "/.../My HDD"不要放置rootdir = "/.../My\ HDD"(注意“ s” [我之所以这么明确,是因为您可能不熟悉python。打算。]
  3. 更改logfile为所需的日志文件位置。最后,该文件将包含重命名的文件列表-供将来参考。
  4. 致电python rename.py

警告:在冒整个GB的音乐风险之前,请先对一个小样本进行测试。

详细信息:重命名是从最里面的文件向外执行的。


0

我意识到这是一个非常古老的职位。AeroGT80的递归解决方案非常彻底,但是速度很慢。我在较慢的服务器上将其运行了大约半小时,但仅完成了一半-我认为在大约300个子目录中大约有73,000个文件。

下面的解决方案将更快地运行(使用AeroGT80的非递归解决方案,它可以处理目录中的所有文件,而不是一个一个地处理每个文件)。唯一的问题是,它只能深入一个目录(因此它不像他的解决方案那样完全递归),但是我敢肯定它可以很容易地被修改。

#!/bin/bash
for D in *; do
        if [ -d "${D}" ]; then
                #echo "${D}"
                pushd "${D}" > /dev/null
                rename 's|:|-|g' *
                popd > /dev/null
        fi
done
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.