如何使用来自单独 .txt 文件的信息重命名多个文件?

如何使用来自单独 .txt 文件的信息重命名多个文件?

我相信这个问题可以通过 bash 脚本解决,但我还是个初学者,所以我需要你的帮助。

我有许多文件(约 800 万个!),其名称如IR.AZR..SHE.D.2016.001.000000.SAC。文件名遵循以下格式:

IR.(stations name)..(component).D.(year).(day).000000.sac

它们都需要重命名为以下格式:

(station name).IR.(component).(year).(day).(begin time).(endtime).sac

注意:(day)是 365 格式,或者我应该说是儒略日格式。

当前文件名以及新格式所需的附加信息存储在纯文本文件中:

文件名的屏幕截图,其中包含重命名所需的附加数据

除了屏幕截图之外,这里是文件的一部分:

IR.AZR..SHE.D.2016.158.071819.SAC  2016 158  7 18 19 300        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072153.SAC  2016 158  7 21 53 540        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072251.SAC  2016 158  7 22 51  60        0.0000        8.1000
IR.AZR..SHE.D.2016.158.072315.SAC  2016 158  7 23 15 580        0.0000       16.3000
IR.AZR..SHE.D.2016.158.072340.SAC  2016 158  7 23 40 180        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072421.SAC  2016 158  7 24 21 300        0.0000        8.1000
IR.AZR..SHE.D.2016.158.072445.SAC  2016 158  7 24 45 980        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072518.SAC  2016 158  7 25 18  60        0.0000        7.3000
IR.AZR..SHE.D.2016.158.072541.SAC  2016 158  7 25 41 620        0.0000       32.9000
IR.AZR..SHE.D.2016.158.072647.SAC  2016 158  7 26 47 540        0.0000       16.4000
IR.AZR..SHE.D.2016.158.072712.SAC  2016 158  7 27 12 260        0.0000        8.1000
IR.AZR..SHE.D.2016.158.072736.SAC  2016 158  7 27 36 860        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072753.SAC  2016 158  7 27 53 340        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072809.SAC  2016 158  7 28  9 820        0.0000        8.1000
IR.AZR..SHE.D.2016.158.072904.SAC  2016 158  7 29  4 740        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072921.SAC  2016 158  7 29 21 220        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072954.SAC  2016 158  7 29 54  60        0.0000        8.2000
IR.AZR..SHE.D.2016.158.073035.SAC  2016 158  7 30 35 260        0.0000        8.1000
IR.AZR..SHE.D.2016.158.073059.SAC  2016 158  7 30 59 940        0.0000        8.2000
  • 第一的列是我的文件列表,其中包含其当前文件名。
  • 第二该列代表的是(year)
  • 第三采用(day)儒略日格式。
  • 第八第九列分别为(begin time)(end time)

简而言之,该脚本应该执行以下操作:

先列出所有文件然后找到这个.txt文件里面的文件和对应的行和列然后按照我上面说的重命名。

答案1

您的要求可以通过 Perl 单行命令轻松完成:

perl -lane '@a=split/\./,$F[0]; rename "old/$F[0]","new/$a[1].IR.$a[3].$F[1].$F[2].$F[7].$F[8].sac"' input.txt

然而,您的新格式命名方案似乎不适合您的输入文件,因为它会创建重复的名称。例如:

IR.AZR..SHE.D.2016.158.071819.SAC  2016 158  7 18 19 300        0.0000        8.2000
IR.AZR..SHE.D.2016.158.072153.SAC  2016 158  7 21 53 540        0.0000        8.2000

都将转换为:AZR.IR.SHE.2016.158.0.0000.8.2000.sac。显然,任何时间都只能有一个具有给定文件名的文件,其中一个将会丢失。

请考虑重复项,重新考虑输出文件名格式。一种可能的替代方案可能是:

perl -lane '@a=split/\./,$F[0]; rename "old/$F[0]","new/$a[1].IR.$a[3].$F[1].$F[2].$a[7].$F[7].$F[8].sac"' input.txt

测试运行

初始文件结构:

old:
IR.AZR..SHE.D.2016.158.071819.SAC
IR.AZR..SHE.D.2016.158.072153.SAC
IR.AZR..SHE.D.2016.158.072251.SAC
IR.AZR..SHE.D.2016.158.072315.SAC
IR.AZR..SHE.D.2016.158.072340.SAC
IR.AZR..SHE.D.2016.158.072421.SAC
IR.AZR..SHE.D.2016.158.072445.SAC
IR.AZR..SHE.D.2016.158.072518.SAC
IR.AZR..SHE.D.2016.158.072541.SAC
IR.AZR..SHE.D.2016.158.072647.SAC
IR.AZR..SHE.D.2016.158.072712.SAC
IR.AZR..SHE.D.2016.158.072736.SAC
IR.AZR..SHE.D.2016.158.072753.SAC
IR.AZR..SHE.D.2016.158.072809.SAC
IR.AZR..SHE.D.2016.158.072904.SAC
IR.AZR..SHE.D.2016.158.072921.SAC
IR.AZR..SHE.D.2016.158.072954.SAC
IR.AZR..SHE.D.2016.158.073035.SAC
IR.AZR..SHE.D.2016.158.073059.SAC

new:

使用 OP 的原始格式进行测试运行:

old:

new:
AZR.IR.SHE.2016.158.0.0000.16.3000.sac
AZR.IR.SHE.2016.158.0.0000.16.4000.sac
AZR.IR.SHE.2016.158.0.0000.32.9000.sac
AZR.IR.SHE.2016.158.0.0000.7.3000.sac
AZR.IR.SHE.2016.158.0.0000.8.1000.sac
AZR.IR.SHE.2016.158.0.0000.8.2000.sac

使用改变的输出格式进行测试运行:

old:

new:
AZR.IR.SHE.2016.158.071819.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.072153.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.072251.0.0000.8.1000.sac
AZR.IR.SHE.2016.158.072315.0.0000.16.3000.sac
AZR.IR.SHE.2016.158.072340.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.072421.0.0000.8.1000.sac
AZR.IR.SHE.2016.158.072445.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.072518.0.0000.7.3000.sac
AZR.IR.SHE.2016.158.072541.0.0000.32.9000.sac
AZR.IR.SHE.2016.158.072647.0.0000.16.4000.sac
AZR.IR.SHE.2016.158.072712.0.0000.8.1000.sac
AZR.IR.SHE.2016.158.072736.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.072753.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.072809.0.0000.8.1000.sac
AZR.IR.SHE.2016.158.072904.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.072921.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.072954.0.0000.8.2000.sac
AZR.IR.SHE.2016.158.073035.0.0000.8.1000.sac
AZR.IR.SHE.2016.158.073059.0.0000.8.2000.sac

答案2

纯 Bash +mv(1)

while read -r current year day d e f g begin end; do
  station="${current:3:3}" component="${current:8:3}"
  mv -T -- "$current" "${station}.IR.${component}.${year}.${day}.${begin}.${end}.sac"
done < file-name-data.txt

mv尽管有 800 万个文件,但每个文件的执行速度都会很慢。因此我推荐以下替代方案。

Python 3

单行代码(无错误处理)

python3 -c 'import sys, os, re; for m in map(re.compile(sys.argv[1]).match, sys.stdin): os.rename(m.group("current"), sys.argv[2].format_map(m.groupdict()))' '(?P<current>IR\.(?P<station>\S+?)\.\.(?P<component>\S+?)\.\S*)\s+(?P<year>\S+)\s+(?P<day>\S+)\s+(?:\S+\s+){4}(?P<begin>\S+)\s+(?P<end>\S+)' '{station}.IR.{component}.{year}.{day}.{begin}.{end}.sac' < file-name-data.txt

完整程序(带错误处理)

#!/usr/bin/python3
import sys, os, re

src_pattern = re.compile(
  r'(?P<current>IR\.(?P<station>\S+?)\.\.(?P<component>\S+?)\.\S*)\s+'
  r'(?P<year>\S+)\s+(?P<day>\S+)\s+'
  r'(?:\S+\s+){4}'
  r'(?P<begin>\S+)\s+(?P<end>\S+)'
)
dst_format = '{station}.IR.{component}.{year}.{day}.{begin}.{end}.sac'

for i, line in enumerate(sys.stdin, 1):
  m = src_pattern.match(line)
  if m:
    try:
      os.rename(m.group('current'), dst_format.format_map(m.groupdict()))
    except OSError as ex:
      print(ex, file=sys.stderr)
  else:
    print(
      'Non-matching source line {:d}: {!r}'.format(i, line.rstrip('\r\n')),
      file=sys.stderr)

用法:

python3 rename.py < file-name-data.txt

答案3

有一个命令行工具,multiple move。它允许您根据模式移动(也就是重命名)、复制等。使用以下命令安装它:

sudo apt install mmv

在终端窗口中。然后运行“man mmv”查看手册页,或者查看此处: https://www.systutorials.com/docs/linux/man/1-mmv/

这可能有点令人畏惧,因为问题并不简单。总是首先在数据副本上进行测试。

还有一个图形工具 filebot。它用 Java 编写,可在 Ubuntu 上运行。只需在 Ubuntu 软件商店中搜索它或使用以下命令安装

sudo apt install filebot

它的主要目标是批量重命名视频和音乐文件,并且可以使用 MusicBrainz 等的数据库信息,但如果我没记错的话(但请自己检查一下,因为这个周末我没怎么睡觉 :) )也适用于非媒体文件集。他们的网站在这里: https://www.filebot.net/

相关内容