系统生成的 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]))
使用
- 将脚本复制到一个空文件中,另存为
rename_files.py
使用目录作为参数运行它:
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*