按顺序重命名所有嵌套子文件夹中的所有 jpeg 文件并移至新文件夹

按顺序重命名所有嵌套子文件夹中的所有 jpeg 文件并移至新文件夹

我的问题与此类似

https://stackoverflow.com/questions/54811336/rename-jpeg-files-sequencely-in-multiple-subfolders

但我的文件夹结构是这样的

├── mainfolder
|    ├── subfolder1
|    |   ├── 01folder
             |--02folder
                 |--03folder 
                      |--- 0001.jpg
|    |                └── 0002.jpg
                      ...
|    |                └── 0250.jpg
|    |
|    ├── subfolder2
           |── 01folder
                |--02folder
                     |--03folder 
|    |                  ├── 0001.jpg
|    |                  └── 0002.jpg
                         ...
|    |                  └── 0250.jpg
|    |
|    ├── subfolder3
           ├── 01folder
                 |--02folder
                     |--03folder  
|    |                   ├── 0001.jpg
|    |                   └── 0002.jpg
                         ...
|    |                   └── 0250.jpg

所有文件夹都有 jpg 图像,编号从 1 到 250,总共 100000 张图像。我想移动所有文件并在移动之前重命名它们,以便文件夹结构如下所示

├── newfolder
|    |--1.jpg
|    |--2.jpg
|    |--3.jpg
...
|    |--100000.jpg

我目前正在使用这个

将嵌套子目录中的所有文件移动到新目录

find ~/mainfolder/ -type f -print0 | xargs -0 mv -t ~/newfolder/

如何将文件从嵌套子目录移到 ubuntu 中的另一个文件夹?(尝试删除许多子文件夹)

不确定如何重命名它们,因为移动时它们会因名称相同而互相覆盖,从而导致只有 250 个文件而不是 100000 个文件。

答案1

使用 Larry Wall 的rename/ prename(*),您可以轻松地“扁平化”结构:

cd mainfolder
rename -n 's:/:-:g' */*/*.jpg

这将移动subfolder1/0001.jpgsubfolder1-0001.jpg(在mainfolder)因为rename编辑整个输入路径然后执行与mv使用源和编辑的名称等效的操作。

  • g在编辑中意味着替换所有出现的条目,如果您有多个级别的子目录则很有用。
  • -n只是显示了它会做什么,却什么也不做
  • 删除或替换-v为实际操作。
  • 默认情况下不会发生覆盖(您需要一个-f),但通常因为这在名称中包含子目录,所以您不应该有名称冲突。
  • 一旦一切就绪mainfolder,如果需要的话,很容易将大量物品转移到其他地方。
  • 如果文件处于不同层次的嵌套中,则使用shopt -s globstar和 使用**来表示所有层次:

    rename s:/:-:g **/*.jpg
    

例如:

从...开始

.
├── sub1
│   ├── subsub1
│   │   ├── 001.jpg
│   │   ├── 002.jpg
│   │   └── 003.jpg
│   └── subsub2
│       ├── 001.jpg
│       ├── 002.jpg
│       └── 003.jpg
└── sub2
    ├── subsub1
    │   ├── 001.jpg
    │   ├── 002.jpg
    │   └── 003.jpg
    └── subsub2
        ├── 001.jpg
        ├── 002.jpg
        └── 003.jpg

执行:

rename s:/:-:g */*/*.jpg

其结果是:

.
├── sub1
│   ├── subsub1
│   └── subsub2
├── sub1-subsub1-001.jpg
├── sub1-subsub1-002.jpg
├── sub1-subsub1-003.jpg
├── sub1-subsub2-001.jpg
├── sub1-subsub2-002.jpg
├── sub1-subsub2-003.jpg
├── sub2
│   ├── subsub1
│   └── subsub2
├── sub2-subsub1-001.jpg
├── sub2-subsub1-002.jpg
├── sub2-subsub1-003.jpg
├── sub2-subsub2-001.jpg
├── sub2-subsub2-002.jpg
└── sub2-subsub2-003.jpg

您可以使用以下方法删除子目录

rm -r sub*/

(最后的斜线很重要!它将匹配限制在目录中)

最后:

.
├── sub1-subsub1-001.jpg
├── sub1-subsub1-002.jpg
├── sub1-subsub1-003.jpg
├── sub1-subsub2-001.jpg
├── sub1-subsub2-002.jpg
├── sub1-subsub2-003.jpg
├── sub2-subsub1-001.jpg
├── sub2-subsub1-002.jpg
├── sub2-subsub1-003.jpg
├── sub2-subsub2-001.jpg
├── sub2-subsub2-002.jpg
└── sub2-subsub2-003.jpg

如果您有大量文件,则无法在一次调用中处理,因为 **/*.jpg 的文件扩展名将生成一个太长的列表 (/bin/sh: 1: rename: 参数列表太长`)。因此,您必须拆分工作,例如通过目录调用一次 rename:

shopt -s globstar 
for d in **/; do rename s:/:-:g "$d"*.jpg; done

/'**/' 中的很重要,它限制了目录的扩展)

如果您仍然收到该Argument list too long消息,则说明您的目录中包含很多文件:)您只需找到一种方法来拆分工作,例如:

for f in path/to/hugedir/A*;jpg; do rename s:/:-:g "$d"*.jpg; done
for f in path/to/hugedir/B*;jpg; do rename s:/:-:g "$d"*.jpg; done
[... etc ...]

如果这仍然太大或者您想要直截了当,您也可以为每个文件调用一次重命名:

shopt -s globstar 
for f in **/*.jpg; do rename s:/:-:g "$f"; done

(这会起作用,因为这里“**/*.jpg”的扩展只是 shell 中的一个变量,而不是命令的参数列表)。

PS:bash这里假设,如果你把它放在脚本中,请确保“shebang”是/bin/bash,在某些系统上是一个不支持的sh轻量级shell( ) 。dashglobstar

(*) 名称因发行版而异,rename对于 Debian/Ubuntu 及其衍生产品,以及 IIRCprename对于 RedHat 及其衍生产品。

答案2

我最终这样做了

改名

import os


def main():
    path = "/path/"
    count = 1

    for root, dirs, files in os.walk(path):
        for i in files:
            os.rename(os.path.join(root, i), os.path.join(root, "changed" + str(count) + ".jpg"))
            count += 1


if __name__ == '__main__':
    main()

然后移动到父目录

find /main/ -type f -print0 | xargs -0 mv -t /dest/

相关内容