【问题标题】:renaming the filename with regex in python using re使用 re 在 python 中使用正则表达式重命名文件名
【发布时间】:2018-02-27 07:36:50
【问题描述】:

我有一个文件夹,其中包含多个具有以下文件名的文件,例如,我有多个不同的文件

_EGAZ00001018697_2014_ICGC_130906_D81P8DQ1_0153_C2704ACXX.nopd.AOCS_001_ICGCDBDE20130916001.rsem.bam

现在我想重命名然后仅使用 ICGCDBDE20130916001.rsem.bam 将根据路径中的文件而改变。与名称 *.rsem.bam 对应的字符串应该是用“_”分隔的字符串。所以对于目录中的所有文件都应该相应地替换为这个。我正在考虑使用正则表达式,所以我想出了以下模式

pat=r'_(.*)_(.*)_(.*)_(.*)_(.\w+)'

这会根据需要分离出我的文件名,我可以使用全局变量重命名文件名,其中我只使用pat[4]。我想使用 python,因为我想从现在开始学习它以进行小的更改,例如文件重命名等等,然后随着时间的推移在 python 中转换我的工作流程。我做不到。我应该如何在 python 中完成这项工作?我也在修复什么应该是相应的 bash 正则表达式,因为这是一个非常大的文件名,而我遇到这样的文件名是非常新的。下面是我的代码,不要直接更改,而是要了解它是否有效,但是如果我想重命名它们,我应该如何让它工作。

import re
import os
_src = "path/bam/test/"
_ext = ".rsem.bam"
endsWithNumber = re.compile(r'_(.*)_(.*)_(.*)_(.*)_(.\w+)'+(re.escape(_ext))+'$')
print(endsWithNumber)
for filename in os.listdir(_src):
    m = endsWithNumber.search(filename)
    print(m)

我会很欣赏 python 和 bash,但是,我更喜欢 python 以供我自己理解和未来学习。

【问题讨论】:

    标签: python bash sed


    【解决方案1】:

    您可以使用rpartition,它将您想要的部分与其余部分分离成一个三部分的元组。

    给定:

    >>> fn
    '_EGAZ00001018697_2014_ICGC_130906_D81P8DQ1_0153_C2704ACXX.nopd.AOCS_001_ICGCDBDE20130916001.rsem.bam'
    

    你可以这样做:

    >>> fn.rpartition('_')
    ('_EGAZ00001018697_2014_ICGC_130906_D81P8DQ1_0153_C2704ACXX.nopd.AOCS_001', '_', 'ICGCDBDE20130916001.rsem.bam')
    

    然后:

    >>> _,sep,new_name=fn.rpartition('_')
    >>> new_name
    'ICGCDBDE20130916001.rsem.bam'
    

    如果你想使用正则表达式:

    >>> re.search(r'_([^_]+$)', fn).group(1)
    'ICGCDBDE20130916001.rsem.bam'
    

    实际上,您会在使用 group(1) 之前测试是否有匹配项:

    >>> m=re.search(r'_([^_]+$)', fn)
    >>> new_name = m.group(1) if m else fn
    

    对于sed,您可以这样做:

    $ echo "$fn" | sed -E 's/.*_([^_]*)$/\1/'
    ICGCDBDE20130916001.rsem.bam
    

    或者在 Bash 中,同样的正则表达式:

    $ [[ $fn =~ _([^_]*)$ ]] && echo "${BASH_REMATCH[1]}"
    ICGCDBDE20130916001.rsem.bam
    

    【讨论】:

      【解决方案2】:

      你可以使用列表推导

      import re
      import os
      _src = "path/bam/test/"
      new_s = [re.search("[a-zA-Z0-9]+\.rsem\.bam", filename) for filename in os.listdir(_src)]
      for first, second in zip(os.listdir(_src), new_s):
          if second is not None:
               os.rename(first, second.group(0))
      

      【讨论】:

      • 我无法完成这一项。我们不需要像for filename in os.listdir(_src): 之前循环吗?即使我只是将 _src 作为路径编写,我也会遇到语法错误。
      • @vchris_ngs 请立即尝试使用上面的代码。让我知道它是否有效。
      • 我收到以下错误,Traceback (most recent call last): File "testRname.py", line 4, in <module> new_s = [re.search("[a-zA-Z0-9]+\.rsem\.bam", filename).group(0) for filename in os.listdir(_src)] File "testRname.py", line 4, in <listcomp> new_s = [re.search("[a-zA-Z0-9]+\.rsem\.bam", filename).group(0) for filename in os.listdir(_src)] AttributeError: 'NoneType' object has no attribute 'group'
      • @vchris_ngs 请立即尝试。我忘了说明目录中的某些文件名与指定的模式不匹配。
      • 不应该重命名 dir(_src) 中的文件,打印工作正常,但文件名没有改变。对不起,我的python知识非常有限。 iimport re import os _src = "/marconi_scratch/userexternal/vdas0000/ICGC/data/EGA.Bam/test/" new_s = [re.search("[a-zA-Z0-9]+\.rsem\.bam", filename) for filename in os.listdir(_src)] print(new_s) final_data = [i.group(0) for i in new_s if i is not None] print(final_data) 输出:是列表的形式,那么如何重命名目录中的文件?
      【解决方案3】:

      工作量太大。

      newname = oldname.rsplit('_', 1)[1]
      

      【讨论】:

        【解决方案4】:
        import os  
        fname = 'YOUR_FILENAME.avi'
        fname1 = fname.split('.')
        fname2 = str(fname1[0]) + '.mp4'
        os.rename('path to your source file' + str(fname), 'path to your destination file' + str(fname2))
        fname = fname2
        

        【讨论】:

        • 欢迎来到 Stack Overflow!感谢您提供此代码 sn-p,它可能会提供一些有限的短期帮助。一个正确的解释would greatly improve 其长期价值,通过展示为什么这是解决问题的好方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
        猜你喜欢
        • 2011-04-28
        • 2011-09-14
        • 2017-08-10
        • 1970-01-01
        • 2018-08-22
        • 2020-11-29
        • 2012-08-02
        相关资源
        最近更新 更多