替换目录名称和该目录中文件名中的一个单词

替换目录名称和该目录中文件名中的一个单词

我有一个这样的目录结构:

Bookname Edition 1
  Bookname Edition 1 type1.pdf
  Bookname Edition 1 type2.pdf
Bookname Edition 2
  Bookname Edition 2 type1.pdf
  Bookname Edition 2 type2.pdf

我想递归地将目录的名称从更改EditionVolume这些目录中的文件名。

我从这个开始,如果我在目录中,那就没问题:

for f in *.pdf; do
    a="$(echo $f | sed s/Edition/Volume/)"
    mv "$f" "$a"
done

然后我尝试通过这个来改变目录下的所有文件,但是这时我遇到了困难......

请告诉我如何操作或提供更好的方法。100 个目录中有 15000 个 PDF。

答案1

如果您的结构只有两个级别,则不需要使用递归。

不要使用 来解析文件名sed。如果你想使用正则表达式和sed样式语法来重命名文件,请使用rename。如果你使用的是 Ubuntu 17.10,则需要安装它

sudo apt install rename

然后你可以使用pa4080 的回答

使用rename,使用-n选项进行测试。

rename -n 'expression' file(s)

您也可以直接使用mv命令。作为一行命令:

for d in ./*/; do mv -v "$d" "${d/Edition/Volume}"; done; for f in ./*/*; do mv -v "$f" "${f/Edition/Volume}"; done

您可以使用echo进行测试mv,即echo mv -v source dest,但它会在这里给出不准确的结果,除非您测试然后单独运行循环。

作为脚本:

#!/bin/bash

# rename directories first
for d in ./*/; do
    mv -v "$d" "${d/Edition/Volume}"
done

# now rename files
for f in ./*/*; do
    mv -v "$f" "${f/Edition/Volume}"
done

mvrename识别--表示选项的结束。由于./本例中所有路径都以 开头,我们不需要使用它,但如果路径可以以 开头,则在选项末尾-使用,例如,以防止这些路径被解释为选项。--rename -n -- 's/foo/bar/' *

答案2

rename你可以使用两次该命令来完成此任务:

rename 's/Edition/Volume/' */        # rename the directories
rename 's/Edition/Volume/' */*.pdf   # rename the PDF files inside

以下是两个类似的问题:

答案3

在多级目录中,您可以一步完成此操作,但问题是您需要确保从下到上重命名目录,以防止命令或脚本在更改目录内容之前更改目录名称。

在python中,你可以使用:

os.walk

结合

topdown=False

在脚本中:

#!/usr/bin/env python3
import os
import shutil
import sys

for root, dirs, files in os.walk(sys.argv[1], topdown=False):
    for f in files:
        shutil.move(
            root+"/"+f, root+"/"+f.replace("Edition", "Volume").strip()
        )
    for dr in dirs:
        shutil.move(
            root+"/"+dr, root+"/"+dr.replace("Edition", "Volume").strip()
        )

将脚本另存为change_name.py,并使用目录作为参数运行它:

python3 /path/to/change_name.py <directory>

这可以在任意数量的级别上递归地进行。

答案4

find-depth选项结合使用prename

find [DIRS...] -depth | prename -n 's|Edition(?=[^/]*$)|Volume|'

解释:

  • -depth先选择目录子目录,再选择其父目录。然后,使用所选路径名进行重命名的工具可以先重命名子目录,再重命名其父目录。

  • s|Edition(?=[^/]*$)|Volume|Edition将路径名中第一次出现的替换为Volume 但只有如果余数不包含/,即,它仅适用于最后一个路径名组件(通过正向前瞻实现(?=[^/]*$))。

  • -n告诉prename不要真正重命名路径,而是打印如何重命名它们。删除此选项即可真正重命名它们。

相关内容