1

I want to rename all files within a directory to match the parent folder's name.

Now I've found several results that sort of do what I want, but they all seem to rely on a static filetype, path, format, etc.

I need one that takes any crazy folder name and applies it to any files within, leaving their extension unchanged. I don't want the Parent's Parent's Parent, etc. Just something I can run in a current folder to affect all sub-folders within that folder.

For example:

Folder structure

This.Is.A.Crazy.Name.S00E00.720p
|
| asdfasdfasdfasdfasdfasdfafs.mkv
|
| info.nfo
|
| proof.jpg
|
You.See.Where.This.Is.Going.14x01.480p.crappo
|
| video.mp4

Expected result

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

Could anyone advise how this can be done in a script or a single, long command?

Zanna
  • 72,312
DGC
  • 33

1 Answers1

4

You can use rename for that:

rename -n 's/(.*)\/.*\./$1\/$1./' */*

This command needs to be started in the directory directly above the directories you want to process, exactly like in your example. It will first only list the changes for you to check, if you're happy with the results run it without -n to perform the renaming.

If there are multiple files with the same extension in one directory, rename will print a warning for every file and just leave them out. You could force overwriting with -f, but I highly doubt that's what you want to be done in these (rare?) cases.

Example run

$ 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

Explanation

rename 's/(.*)\/.*\./$1\/$1./' */*
  • s/a/b/substitute a by b
  • (.*)\/.*\. – take everything until (excl.) the last slash saving it as group 1 and take the slash and everything until (incl.) the last dot
    and substitute it by
  • $1\/$1. – group 1 (dir name), a slash, group 1 again (file name) and a dot (dot before extension, which itself didn't get touched)
dessert
  • 40,956