如何在bash或python中将文件路径中的部分目录名称附加到文件名称中?

时间:2018-11-19 02:21:10

标签: python bash directory rename filenames

我最近从MacOS系统中解放了自己。我最关心的是保存在iPhoto中保存的十四年家庭图像。

我决定导出所有17000+张图像,并将它们放入按年,月和日组织的文件夹树中。问题在于文件本身不包含有关何时拍摄图像的信息。唯一可确定何时拍摄图像的属性是图像所在的文件夹。

现在,我的“图片”文件夹树如下所示:

 2004/    
 2005/    
 2006/    
 2007/    
 2008/    
 2009/    
 2010/    
 2011/    
 2012/    
      01_January/    
      02_February/    
      03_March/    
      04_April/    
      05_May/    
      06_June/       
           18June, 2012/    
                File - 001.jpg     
                File - 002.jpg    
                File - 003.jpg    
                etc...    
           24June, 2012/    
                File - 001.jpg    
                File - 002.jpg    
                File - 003.jpg    
                etc...    
      07_July/    
      08_August/    
      09_September/    
      10_October/    
      11_November/    
      12_December/
 2013/    
 2014/    
 2015/    
 2016/    
 2017/    
 2018/   

每年目录包含十二个月目录。仅当当天有图像时,每个月目录才包含日目录。

我要做的是附加所有图像文件名,以便它们包含其上级目录中的元素:

示例:

 ./2012/06_June/18June, 2012/      
      File - 001.jpg   ------->   2012-06-18_File - 001.jpg    
      File - 002.jpg   ------->   2012-06-18_File - 002.jpg    
      File - 003.jpg   ------->   2012-06-18_File - 003.jpg     
      etc...

有人可以帮我找到一种方法吗? Python或Bash脚本,我可以用两种方法学习如何做到这一点。 谢谢。

3 个答案:

答案 0 :(得分:0)

假设您位于“图片”文件夹中,则可以尝试以下代码。请首先检查新名称是否正确,然后取消注释注释行。

from glob import glob
import os
import re
for i in os.scandir(os.getcwd()):
    if i.is_dir():
        year = i.name
        os.chdir(i.name)
        for j in os.scandir(os.getcwd()):
           if j.is_dir() and os.listdir(j.name):
               month = re.compile(r'(\d+)').split(j.name)[-2]
               os.chdir(j.name)
               for k in os.scandir(os.getcwd()):
                   if k.is_dir():
                       day = re.compile(r'(\d+)').split(k.name)[-4]
                       os.chdir(k.name)
                       for l in glob('*.jpg'):
                           newName = year + '-' + month + '-' + day + '_' + l
                           print(l)
                           print(newName)
                           # os.rename(l, newName)
                       os.chdir('..')
               os.chdir('..')
        os.chdir('..')

答案 1 :(得分:0)

这是一种(Shellcheck-干净的Bash解决方案:

#! /bin/bash

shopt -s nullglob   # Globs that match nothing expand to nothing

for file_path in [12][0-9][0-9][0-9]/[01][0-9]_*/[0-3][0-9]*/*.jpg ; do
    IFS=/ read -r year month_name day_month_year file_name <<<"$file_path"
    month=${month_name%%[^0-9]*}
    day=${day_month_year%%[^0-9]*}

    day_month_year_path=${file_path%/*}
    new_file_name=${year}-${month}-${day}_${file_name}
    new_file_path=${day_month_year_path}/${new_file_name}

    printf '    %s   ------->   %s\n' \
        "$file_path" "$new_file_path" >&2

    #UNCOMMENT mv -- "$file_path" "$new_file_path"
done

在包含年份目录(2004,...)的目录中运行它。

如果您满意它会正确地重命名文件,请从#UNCOMMENT行的开头删除mv,然后再次运行以实际重命名文件。

有关IFS=/ read -r ... <<<"$file_path"行的工作方式,请参见How do I split a string on a delimiter in Bash?

有关${var##pattern}${var%%pattern}的信息,请参见Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?))

有关模式的信息,请参见glob - Greg's Wiki,例如for行,*/[^0-9]*上的模式。

答案 2 :(得分:-1)

我拥有的解决方案是使用python,只需在PATH中查找所有文件,然后使用String的总和创建图像名称