Renomeie os arquivos de acordo com as pastas pai e mova para o novo local [closed]

1

Eu tenho uma estrutura de diretórios como esta:

./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

E preciso renomear o 00001.mpeg como as pastas pai como essa para cada pasta em ./ Preciso da data e hora da gravação nesse formato, por exemplo - não preciso de 2017 no novos nomes de arquivos

E, no final, preciso mover todos os arquivos mpeg renomeados para um novo caminho como este:

./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
Primeiro de tudo eu uso o Fedora 20 (eu sei que aqui é o fórum do Ubuntu) e quando executo o comando mv ele não suporta a opção -v e só tem essa opção:

-f -i -n

E você deve saber no caminho de origem meu gravador de vídeo fazer novo arquivo a cada 1 hora.

Então, eu preciso de um script recursivo para fazer isso para todos os arquivos durante a pasta fonte apenas para o arquivo .mpeg (eu usarei o script depois que funcionou para mim no cron) mas nenhum dos scripts enviados aqui funciona para mim agora.

    
por lockheed 20.09.2017 / 13:19

3 respostas

2

Desde que você mencionou que você tem o Fedora, aqui está um script Python para você, que usa a sintaxe do Python 2, que deve funcionar sem problemas ou diferenças tanto no Ubuntu quanto no Fedora. (Seria bom usar o prename que os derivados do Debian usam por padrão, mas infelizmente o Fedora não. Vou deixar isso como um exercício para o futuro, e o prename ainda é útil para usuários do Ubuntu.)

Aqui está o próprio script:

#!/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()

Aqui está em ação:

$ ./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

Eu sugiro que você substitua shutil.copy() part por shutil.move() , ou você pode simplesmente se livrar do diretório antigo no final, mas deixarei isso para você decidir.

As regras são simples: chame o script com fonte como argumento 1 e destino como argumento 2 para o script do diretório um nível acima de BBC_english . No geral, o script é rápido e sujo, a renomeação é codificada; Ninguém diria que não é ideal, mas funciona.

    
por Sergiy Kolodyazhnyy 21.09.2017 / 10:16
2

Como o heemayl sugere em resposta ao post relacionado, você pode usar uma série de expansões de shell.

Assumindo que o diretório de trabalho atual é o pai da origem e do destino, você pode usar esse loop em um sistema Ubuntu:

$ 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

Observe que fazemos um loop pelos diretórios em vez dos arquivos. Isso pressupõe que você realmente tenha apenas um arquivo em cada diretório, o que parece ser o caso, dada a lógica.

Remova echo após o teste para mover arquivos. Então, -v faz com que mv relate o que está fazendo.

Se o seu mv não der suporte ao sinalizador -v (detalhado) e você quiser ver o que está acontecendo, você pode obter o bash para ser detalhado e fornecer um resumo detalhado do que está fazendo usando 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

A saída disso após remover echo incluiria o resultado de cada expansão e a instrução mv para cada iteração do loop. Para a primeira iteração, a saída ficaria assim:

+ 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
    
por Zanna 20.09.2017 / 14:13
0

Este script deve ajudar:

#!/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
    
por George Udosen 20.09.2017 / 18:34