根据父文件夹重命名文件并移动到新位置

根据父文件夹重命名文件并移动到新位置

我有一个这样的目录结构:

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

我需要将00001.mpeg./ 中的每个文件夹重命名为父文件夹,例如,我需要以这种格式记录的日期和时间 - 我不需要2017新的文件名

最后我需要将所有重命名的 mpeg 文件移动到新路径,如下所示:

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

首先,我使用 Fedora 20(我知道这里是 Ubuntu 论坛),当我执行mv命令时,它不支持-v选项,只有这个选项:

-f -i -n

您应该知道,在源路径中,我的视频录像机每小时创建新文件一次。

因此,我需要一个递归脚本来对源文件夹中的所有文件执行此操作(仅针对 .mpeg 文件)(之后我将在 cron 中使用该脚本)但到目前为止,您在此处发送的脚本均不适合我。

答案1

既然您提到您使用的是 Fedora,这里有一个 Python 脚本,它使用 Python 2 语法,在 Ubuntu 或 Fedora 上都可以正常工作,不会出现任何问题或差异。(如果使用prename默认提供的 Debian 衍生产品就好了,但不幸的是 Fedora 没有。我将把它留作将来的练习,prename对 Ubuntu 用户仍然有用。)

脚本本身如下:

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

实际操作如下:

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

我建议您shutil.copy()用 替换部分shutil.move(),或者您最终可以摆脱旧目录,但我会让您自己决定。

规则很简单:从上一级目录中调用脚本,将源作为参数 1,将目标作为参数 2。BBC_english总的来说,这个脚本既快又脏,重命名是硬编码的;有人会说它并不理想,但它确实有效。

答案2

希梅尔建议为了回答链接的帖子,您可以使用一系列 shell 扩展。

假设当前工作目录是源和目标的父目录,您可以在 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

请注意,我们循环遍历的是目录而不是文件。这假设每个目录中实际上只有一个文件,从逻辑上看似乎确实如此。

测试后删除echo以实际移动文件。然后-v报告mv其正在做什么。

如果你mv不支持-v(verbose) 标志,但又想看看发生了什么,你可以让 bash 变得详细,并为你提供正在执行的操作的详细摘要,方法是使用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

删除后,此输出echo将包括每次扩展的结果和mv循环每次迭代的语句。对于第一次迭代,输出将如下所示:

+ 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

答案3

该脚本应该有帮助:

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

相关内容