1

I have a directory structure like this:

./BBC_english/

 2017-09-19.20.00.3-0.rec/00001.mpeg
 2017-09-19.21.00.3-0.rec/00001.mpeg
 2017-09-19.22.00.3-0.rec/00001.mpeg
 2017-09-19.23.00.3-0.rec/00001.mpeg

And I need to rename the 00001.mpeg as the parent folders like this for every folder in ./ I need the date of day and time of recording in this format for example - I don't need 2017 in the new file names

And in the end I need to move all renamed mpeg files to a new path like this :

./newpath/

BBC_english__09-19__20.00.mpeg   
BBC_english__09-19__21.00.mpeg    
BBC_english__09-19__22.00.mpeg
BBC_english__09-19__23.00.mpeg

First of all I use Fedora 20 (I know here is Ubuntu forum) and when I execute mv command it does not support -v option and only have this options:

-f -i -n

And you should know in the source path my Video recorder make new file every 1 hour.

So I need a recursive script to do that for all files during source folder only for .mpeg file (I will use the script after that worked for me in cron) but none of scripts you send here works for me by now.

Eliah Kagan
  • 119,640

3 Answers3

2

As heemayl suggests in answer to the linked post, you could use a series of shell expansions.

Assuming the current working directory is the parent of both the source and the destination, you could use this loop on an Ubuntu system:

$ for d in ./BBC_english/*; do e="${d##*2017-}"; f="${e%%.[0-9]-[0-9].rec}"; g="${f/./__}"; echo mv -v -- "$d"/* ./newpath/BBC_english__"$g".mpeg; done
mv -v -- ./BBC_english/2017-09-19.20.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__20.00.mpeg
mv -v -- ./BBC_english/2017-09-19.21.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__21.00.mpeg
mv -v -- ./BBC_english/2017-09-19.22.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__22.00.mpeg
mv -v -- ./BBC_english/2017-09-19.23.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__23.00.mpeg

Note that we loop over the directories rather than the files. This assumes you really only have one file in each directory, which seems to be the case given the logic.

Remove echo after testing to actually move files. Then -v causes mv to report what it's doing.

If your mv does not support the -v (verbose) flag and you want to see what's happening, you can instead get bash to be verbose and give you a detailed summary of what it's doing using set -x

#!/bin/bash
set -x

for d in ./BBC_english/*; do 
   e="${d##*2017-}"            # remove everything before and including 2017-
   f="${e%%.[0-9]-[0-9].rec}"  # remove the trailing numbers and `.rec`
   g="${f/./__}"               # replace the first `.` with `__`
 echo mv -- "$d"/* ./newpath/BBC_english__"$g".mpeg
 # move to the new path using the edited directory name
done

The output of this after removing echo would include the result of each expansion and the mv statement for every iteration of the loop. For the first iteration, the output would look like this:

+ for d in ./BBC_english/*
+ e=09-19.20.00.3-0.rec
+ f=09-19.20.00
+ g=09-19__20.00
+ mv -- ./BBC_english/2017-09-19.20.00.3-0.rec/00001.mpeg ./newpath/BBC_english__09-19__20.00.mpeg
Zanna
  • 72,312
2

Since you mentioned that you have Fedora, here's a Python script for you, which uses Python 2 syntax, which should work without any issues or differences on both Ubuntu or Fedora. ( Would be nice to use prename which Debian derivatives ship by default, but unfortunately Fedora doesn't. I'll leave that as an exercise for future, and prename is still useful for Ubuntu users. )

Here's the script itself:

#!/usr/bin/env python

import os
import sys
import shutil

def find_files(start_dir):
    ext_paths = []
    for root,dirs,files in os.walk(start_dir):
        if root == start_dir: continue        
        ext_paths = ext_paths + map( lambda x: os.path.join(root,x),files )
    return ext_paths

def alter_path(path,new_dir):
    newpath = path.replace(".3-0.rec/00001","").replace("2017-","")
    newpath = newpath.replace("BBC_english/","BBC_english__").replace("19.","19__")
    return os.path.join(new_dir,newpath)    

def main():
    for i in find_files(sys.argv[1]):
        print(i,alter_path(i,sys.argv[2]))
        shutil.copy(i,alter_path(i,sys.argv[2]))

if __name__ == '__main__':
    main()

Here it is in action:

$ ./rename_mpegs.py  BBC_english/ newpath/                                                                                        
('BBC_english/2017-09-19.23.00.3-0.rec/00001.mpeg', 'newpath/BBC_english__09-19__23.00.mpeg')
('BBC_english/2017-09-19.20.00.3-0.rec/00001.mpeg', 'newpath/BBC_english__09-19__20.00.mpeg')
('BBC_english/2017-09-19.22.00.3-0.rec/00001.mpeg', 'newpath/BBC_english__09-19__22.00.mpeg')
('BBC_english/2017-09-19.21.00.3-0.rec/00001.mpeg', 'newpath/BBC_english__09-19__21.00.mpeg')
$ tree newpath/                                                                                                                   
newpath/
├── BBC_english__09-19__20.00.mpeg
├── BBC_english__09-19__21.00.mpeg
├── BBC_english__09-19__22.00.mpeg
└── BBC_english__09-19__23.00.mpeg

I'd suggest you replace shutil.copy() part with shutil.move(), or you can just get rid of old directory in the end, but I'll leave that up to you to decide.

Rules are simple: call the script with source as argument 1 and destination as argument 2 to the script from the directory one level above BBC_english. Overall, the script is quick and dirty, renaming is hard-coded; one would say it's not ideal, but it works.

0

This script should help:

#!/bin/bash  

for i in ./BBC_english/*; do
        # Get the path to the file
        path=$(dirname "$(readlink -f "$i")")         

        # get the names for file rename
        f2=$( echo "$path" | grep -Eo "\-[0-9]{2}-[0-9]{2}" | grep -Eo "[0-9]{2}-[0-9]{2}")            
        f1=$( echo "$path" | grep -Eo BBC_english )           
        f3=$(echo "$path" | grep -Eo "\.[0-9]{2}\.[0-9]{2}" | grep -Eo "[0-9]{2}\.[0-9]{2}")                       
        # Rename the files           
        mv -n "$i" ./newpath/"$f1"__"$f2"__"$f3".mpeg

done
derHugo
  • 3,376
  • 5
  • 34
  • 52
George Udosen
  • 37,534