在文件中查找单词的第二个实例并重命名文件

在文件中查找单词的第二个实例并重命名文件

系统生成的 I 文件具有通用文件名。我想要一个可以运行的脚本,该脚本扫描这些文件以查找单词 ProcID 的第二个实例(单词 ProcID 之后是数字),然后使用 ProcID 编号重命名文件。目前我有以下内容:

FILEPATH; awk -F '[:)]' '/ProcID./{printf "mv %s %s.txt\n", FILENAME, $2 | "/bin/sh"; nextfile}' O*.TXT

例如,脚本扫描文件并找到第二个实例(ProcID:0000014778),然后使用此 Proc ID 号重命名该文件。

上述脚本仅找到第一个实例,因此在系统完成文件输出之前文件就被重命名。

答案1

下面的脚本将目录中的所有文件重命名为ID在找到的第二个字符串中,以以下内容开头ProcID:

1. 重命名为第二个匹配字符串中的 id(字面意思;没有扩展名)

在此处输入图片描述

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename if the second instance exists
        new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    except (IndexError, IsADirectoryError):
        pass
    else:
        # rename the file
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))

使用

  1. 将脚本复制到一个空文件中,另存为rename_files.py
  2. 使用目录作为参数运行它:

    python3 /path/to/rename_files.py /path/to/directory_with_files
    

笔记

  • 该脚本采用(精确的)格式:ProcID:0000014778
  • 脚本将不是如果没有第二个实例ProcID(或根本没有),则重命名文件

2. 仅重命名 .txt 文件,并保留扩展名

...然后使用下面的版本,它只会重命名.txt文件并在重命名的文件中保留扩展名。用法完全相同。

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename is the second instance exists
        new = [s for s in open(file).read().split() if all([
            s.startswith("(ProcID:"), f.endswith(".txt")
            ])][1]
    except (IndexError, IsADirectoryError):
        pass
    else:
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]+".txt"))

脚本的作用

  • 它列出了目录中的文件:

    for f in os.listdir(dr)
    
  • 列出文件内的字符串,以ProcID:

    new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    

    结尾[1]提取第二次出现的字符串,以ProcID:([0]为第一个)开头

  • id 的拆分:

    new.split(":")[-1].strip()
    
  • 并使用 id 重命名文件:

    shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))
    

编辑

脚本 1 的 Python2 版本。OP 原来安装了 python2,它需要IOError而不是,IsADirectoryError以防止脚本运行到目录而不是文件时出现错误。

#!/usr/bin/env python
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename if the second instance exists
        new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    except (IndexError, IOError):
        pass
    else:
        # rename the file
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))

...为了完整起见,第二个脚本有一个 python2 版本:

#!/usr/bin/env python
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename is the second instance exists
        new = [s for s in open(file).read().split() if all([
            s.startswith("(ProcID:"), f.endswith(".txt")
            ])][1]
    except (IndexError, IOError):
        pass
    else:
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()+".txt"))

答案2

您的原始脚本很接近,可以对其进行编辑以通过if语句和计数器变量来计算实例:

FILEPATH; awk -F '[:)]' '/ProcID./{ count++; if(count == 2 ){ printf "mv %s %s.txt\n", FILENAME, $2 | "/bin/sh"; nextfile}}' O*.TXT

如果您正在寻找替代解决方案,您可以使用这个 Perl 脚本:

#!/usr/bin/env perl
use strict;
use warnings;

my $cnt=0;
open(my $fh,'<',$ARGV[0]) or die "open failed";
my $new_name;
while ( my $line = <$fh> ){
    $cnt+=1 if $line =~ /ProcID/;
    if($cnt==2){
        chomp $line;
        my @words = split(/[:)]/,$line); 
        $new_name = $words[1] . ".TXT";
        last;
    }
}
if (defined $new_name){
   rename $ARGV[0], $new_name;
}
close($fh)

示例运行:

$ ls
0000014777.TXT  rename_by_procid.pl*

$ ./rename_by_procid.pl 0000014777.TXT                                                                                                

$ ls
0000014778.TXT  rename_by_procid.pl*

相关内容