我想重命名目录中的所有文件以匹配父文件夹的名称。
现在我已经找到了几种可以满足我要求的结果,但它们似乎都依赖于静态文件类型、路径、格式等。
我需要一个可以接受任何奇怪的文件夹名称并将其应用于其中的任何文件,同时保持其扩展名不变的程序。我不需要父级的父级的父级等。我只需要在当前文件夹中运行该程序即可影响该文件夹中的所有子文件夹。
例如:
文件夹结构
This.Is.A.Crazy.Name.S00E00.720p
|
| asdfasdfasdfasdfasdfasdfafs.mkv
|
| info.nfo
|
| proof.jpg
|
You.See.Where.This.Is.Going.14x01.480p.crappo
|
| video.mp4
预期结果
This.Is.A.Crazy.Name.S00E00.720p
|
|_This.Is.A.Crazy.Name.S00E00.720p.mkv
|
|_This.Is.A.Crazy.Name.S00E00.720p.nfo
|
|_This.Is.A.Crazy.Name.S00E00.720p.jpg
|
You.See.Where.This.Is.Going.14x01.480p.crappo
|
| You.See.Where.This.Is.Going.14x01.480p.crappo.mp4
有人可以建议如何在脚本或单个长命令中完成此操作吗?
答案1
您可以使用rename
:
rename -n 's/(.*)\/.*\./$1\/$1./' */*
此命令需要在您要处理的目录的正上方目录中启动,就像您的示例中一样。它首先只会列表您可以检查更改,如果您对结果满意,请运行它而不-n
执行重命名。
如果一个目录中有多个具有相同扩展名的文件,rename
则会为每个文件打印警告,并将它们排除在外。您可以使用 强制覆盖-f
,但我非常怀疑在这些(罕见?)情况下您是否希望这样做。
示例运行
$ tree
.
├── This.Is.A.Crazy.Name.S00E00.720p
│ ├── asdfasdfasdfasdfasdfasdfafs.mkv
│ ├── info.nfo
│ └── proof.jpg
└── You.See.Where.This.Is.Going.14x01.480p.crappo
└── video.mp4
$ rename 's/(.*)\/.*\./$1\/$1./' */*
$ tree
.
├── This.Is.A.Crazy.Name.S00E00.720p
│ ├── This.Is.A.Crazy.Name.S00E00.720p.jpg
│ ├── This.Is.A.Crazy.Name.S00E00.720p.mkv
│ └── This.Is.A.Crazy.Name.S00E00.720p.nfo
└── You.See.Where.This.Is.Going.14x01.480p.crappo
└── You.See.Where.This.Is.Going.14x01.480p.crappo.mp4
解释
rename 's/(.*)\/.*\./$1\/$1./' */*
s/a/b/
–s
替代a
为b
(.*)\/.*\.
– 取出所有内容直到(不包括)最后一个斜线,将其保存为第 1 组,并取出斜线和所有内容直到(包括)最后一个点
并将其替换为$1\/$1.
– 第 1 组(目录名)、一个斜线、再次是第 1 组(文件名)和一个点(扩展名前的点,扩展名本身没有被触及)