views:

237

answers:

3

I am working on something and need to solve the following. I am giving a analogous version of mine problem.

Say we have a music directory, in which there are 200 directories corresponding to different movies. In each movie directory there are some music files.

Now, say a file music.mp3 is in folder movie.mp3 . I want to make a shell script such that it renames the file to movie_music.mp3 and put it in some folder that I mention to it. Basically, all the files in the subdirectories are to be renamed and to be put in a new directory.

Any workaround for this?

A: 

Assuming the following directory tree:

./movie1:
movie1.mp3

./movie2:
movie2.mp3

The following one-liner will create 'mv' commands you can use:

find ./ | grep "movie.*/" | awk '{print "mv "$1" "$1}' | sed 's/\(.*\)\//\1_/'

EDIT:

If your directory structure contains only the relevant directories, you can expand use the following grep instead:

grep "\/.*\/.*"

Notice it looks file anything with at least one directory and one file. If you have multiple inner directories, it won't be good enough.

Am
no der is nothing like movie1 .. say a movie named Spider Man, and another a movie named Titanic.
abhishekgupta92
ur right, i modified the grep
Am
It is not taking care of spaces in the file. maybe renaming the files first so as to remove the spaces and replace them with dashes should help.
abhishekgupta92
+1  A: 

Bash:

newdir=path/to/new_directory;
find . -type d |while read d; do
  find "$d" -type f -maxdepth 1 |while read f; do
    movie="$(basename "$d" |sed 's/\(\..*\)\?//')"
    mv "$f" "$newdir/$movie_$(basename $f)";
  done;
done
wilhelmtell
There is no restriction that files are mp3. They can be of any media type like wav, mpg.. etc.
abhishekgupta92
@abhishekgupta92 I updated the script to look for all files in each directory under the current directory, and move them to `$newdir`. You have to be aware though that if you move all these files into a single directory you are running the risk of losing files. You can minimize the risk by renaming the files (say, `s/\//_-_/g`), but that won't eliminate the risk.
wilhelmtell
+2  A: 

This script receives two arguments: the source folder and the destination folder. It will move every file under any directory under the source directory to the new directory with the new filename:

#!/bin.sh
echo "Moving from $1 to $2"
for dir in "$1"/*; do
  if [ -d "$dir" ]; then
    for file in "$dir"/*; do
      if [ -f "$file" ]; then
        echo "${file} -> $2/`basename "$dir"`_`basename "${file}"`"
        mv "${file}" "$2"/`basename "$dir"`_`basename "${file}"`
      fi
    done
  fi
done

Here is a sample:

bash move.sh dir dir2
Moving from dir to dir2
dir/d1/f1 -> dir2/d1_f1
dir/d1/f2 -> dir2/d1_f2
dir/d2/f1 -> dir2/d2_f1
dir/d2/f2 -> dir2/d2_f2
Aleph
can it accommodate spaces as well in the names of directories and files alike
abhishekgupta92
the script is giving me following error : songs/ZINDA/Kabhi Muskura Ke.mp3 -> test/ZINDA_Kabhi Muskura Ke.mp3mv: target `Ke.mp3' is not a directory
abhishekgupta92
No, it breaks on spaces because `basename` is not properly quoted. More correct would be `mv -v -- "$file" "$2/$(basename -- "$dir")_$(basename -- "$file")"` or something like that
Philipp
thanks phillipp for the patch. this worked like a charm.
abhishekgupta92