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
  • 70,465
DGC
  • 33
  • 1
    so if you have multiple files with the same extension in the directory, then what? – stumblebee Feb 07 '18 at 06:43
  • 1
    What @stumblebee said. This is in general an unsafe thing to do. Two files can't have the same name, so there's a big risk that any batch command to change files to the name of the parent directory will overwrite files. I'd at least add some numbering. – Zanna Feb 07 '18 at 07:00
  • I don't think it's a duplicate as the other question asks how to add the directory name while this question is about replacing it entirely (which adds certain problems ;-)). – dessert Feb 07 '18 at 07:03

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
  • 39,982
  • "-n" Excellent answer! The "Are you sure" crossed my mind. – stumblebee Feb 07 '18 at 07:04
  • Thank you very much! This did exactly what I needed.

    I guess I could have clarified that this data is not in any way critical, so if something in this folder tree where to get messed up somehow, it would not be a disaster.

    I appreciate your help, very much!

    – DGC Feb 07 '18 at 16:02