我的问题与此类似
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.jpg
到subfolder1-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( ) 。dash
globstar
(*) 名称因发行版而异,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/