Pidaus
Pidaus

Reputation: 15

Batch rename multiple files from different path

I have a file directory music/artist/{random_name}/{random_music}.ogg

There's a lot of folder in {random_name} and different kind of music title {random_music}.

So, I wanted to rename the {random_music}.ogg to music.ogg. Each {random_name} folder only have one .ogg files.

I've tried with the Bash scripts for hours but didn't managed to find out.

for f in ../music/artist/*/*.ogg
do
  echo mv  "$f" "${f/.*.ogg/music.ogg}"
done

It only rename the file on my current dir, which will ask for replace/overwrite.

My goals is, I wanted to rename all the {random_music}.ogg files to music.ogg with their respective directories for example,

music/artist/arai/blue.ogg to music/artist/arai/music.ogg

music/artist/sako/sky.ogg to music/artist/sako/music.ogg

Upvotes: 0

Views: 108

Answers (5)

Learner
Learner

Reputation: 1

I hope this would help you:

Previously:

[root@user]# tree music
music
└── artist
    ├── df
    │   └── mp.ogg
    ├── gh
    │   └── pl.ogg
    ├── jk
    │   └── gl.ogg
    ├── po
    │   └── ui.ogg
    ├── ty
    │   └── lk.ogg
    └── ui
        └── dh.ogg

7 directories, 6 files

Source code:

#!/bin/bash

for i in `ls -ld music/artist/* | awk '{print $9}'`
do
        mv $i/*ogg $i/music.ogg

done

After execution:

music
└── artist
    ├── df
    │   └── music.ogg
    ├── gh
    │   └── music.ogg
    ├── jk
    │   └── music.ogg
    ├── po
    │   └── music.ogg
    ├── ty
    │   └── music.ogg
    └── ui
        └── music.ogg

7 directories, 6 files

As you can see all of the files got renamed correctly.

Upvotes: 0

Ribtips
Ribtips

Reputation: 56

find ../music/artist/ -type f -name "*.ogg" -exec bash -c 'mydir=`dirname {}`;mv {} $mydir/music.ogg' \;

This is a one-liner that should work. It implements the exec option of the find command which then gets the directory name and renames the original file to music.ogg.

Upvotes: 0

Akhil Mohan
Akhil Mohan

Reputation: 105

You can change your code like this

for f in ../music/artist/*/*.ogg
do
  echo mv $f "$(dirname "$f")"/music.ogg
done

Here dirname will extract the directory name from your variable and you can append it with your music.ogg to get the desired result.

For the example path that you provided

if $f equals music/artist/arai/blue.ogg, then the result will be

mv music/artist/arai/blue.ogg music/artist/arai/music.ogg

Upvotes: 0

Wiimm
Wiimm

Reputation: 3492

I use usually this:

for f in ../music/artist/*/*.ogg
do
    dest="${f/.*.ogg/music.ogg}"
    if [[ $f != "$dest" ]] # nothing to do if name doesn't change
    then 
        if [[ -a $dest ]]
        then
            printf 'WARNING: File already exists: %s\n' "$dest"
        else
            mv "$f" "$dest"
        fi
    fi
done

Upvotes: 0

Adrian
Adrian

Reputation: 675

Your pattern replacement is incorrect. Because all your paths start with .., .*.ogg actually matches the entire path, so every file gets turned into music.ogg in your current directory.

You want ${f/\/*.ogg/music.ogg} instead, or better yet, ${f%/*}/music.ogg. That's the rough equivalent of "$(dirname "$f")"/music.ogg.

Upvotes: 1

Related Questions