我正在使用(或尝试使用)python脚本(目前)删除和更改文件名
我希望在一个脚本中有一堆重命名功能。
Q1
我想知道怎么做,所以做文件重命名(比如删除'。'而不必在最后为fileextention重新添加它。
Q2
我还希望能够创建一个列表,这样我就可以将多个内容重命名为相同的名称,而不必为每个名称添加一行: 现在它将是:
[os.rename(f, f.replace('B', 'A')) for f in os.listdir('.') if not f.startswith('.')]
[os.rename(f, f.replace('C', 'A')) for f in os.listdir('.') if not f.startswith('.')]
[os.rename(f, f.replace('D', 'A')) for f in os.listdir('.') if not f.startswith('.')]
[os.rename(f, f.replace('E', 'A')) for f in os.listdir('.') if not f.startswith('.')]
[os.rename(f, f.replace('F', 'A')) for f in os.listdir('.') if not f.startswith('.')]
我希望能够把它变成某种完整的“替换B,C,D,E和/或F
Q3
我的第三个问题是我怎么能这样做,所以我可以从文件名中删除所有“ - ”,除非部分相同的是“可口可乐”(或其他)
目前我有几个蹩脚的解决方法。但它们效率不高
答案 0 :(得分:2)
import re
[os.rename(f, re.sub(r'[B-F]', 'A', f)) for f in os.listdir('.') if not f.startswith('.')]
答案 1 :(得分:2)
首先,您确定要使用Python执行此操作吗?有几个功能齐全的文件重命名实用程序可供您使用。 (我个人最喜欢的是Linux下的KRename。)
假设你确实想在python中这样做......
Q1)将文件名与其扩展名分开
使用os.path.splitext()
将文件名分隔为“名称”和“扩展”部分。然后,您可以在不更改扩展名的情况下操作文件名,并在完成后将它们重新组合在一起。例如:
import os, pprint
filenames = [f for f in os.listdir('D:\\Freeware')]
name_and_ext_list = [os.path.splitext(f) for f in filenames]
pprint.pprint(filenames)
pprint.pprint(name_and_ext_list)
给出类似
的输出['a43.zip',
'Amphetype-0.16-win32.exe',
'aMSN-0.98.4-tcl85-windows-installer.exe',
'andlinux-beta2-minimal.exe',
'ATF-Cleaner.exe',
'aurora-setup.exe',
[('a43', '.zip'),
('Amphetype-0.16-win32', '.exe'),
('aMSN-0.98.4-tcl85-windows-installer', '.exe'),
('andlinux-beta2-minimal', '.exe'),
('ATF-Cleaner', '.exe'),
('aurora-setup', '.exe'),
请注意,os.path.splitext()
比您自己可能推出的任何内容都更强大。它不会被文件名中的额外点混淆 - 例如:
>>> os.path.splitext('Zipped Party Food Invoice 22.09.2011.xlsx.zip')
('Zipped Party Food Invoice 22.09.2011.xlsx', '.zip')
Q2)“模糊”搜索并替换
您的示例代码将所有字符BCDEF
替换为A
,可以使用@kev建议的正则表达式来完成。
编辑2 由于您要替换整个单词,而不是特定的单个字符B, C, D, E, F
,您可以尝试类似下面的代码。这不是特别有效(它必须为您要搜索和替换的每个单词扫描一次文件列表) - 它有效,但欢迎改进。一个好的解决方案只需要通过字符串。
def replace_words ( input_string ):
replacement_lists = { \
"Electronics" : ["Computer", "CD Player", "Camera", "Coffee Grinder"],
"Baked Goods" : ["Cheesecake", "Muffin","Cookie"] }
output_string = input_string
for type_of_thing, list_of_things in replacement_lists.iteritems():
for thing in list_of_things:
output_string = output_string.replace(thing, type_of_thing)
return output_string
input_names = [ \
"Coffee Cup.jpg",
"Computer Disks.docx",
"Muffins.jar",
"CD Player Maintenance.lzma",
"Cookie Monster's 101 Types of Cookie.pdf" ]
output_names = [replace_words(x) for x in input_names]
,输出如下:
>>> pprint.pprint(input_names)
['Coffee Cup.jpg',
'Computer Disks.docx',
'Muffins.jar',
'CD Player Maintenance.lzma',
"Cookie Monster's 101 Types of Cookie.pdf"]
>>> pprint.pprint(output_names)
['Coffee Cup.jpg',
'Electronics Disks.docx',
'Baked Goodss.jar',
'Electronics Maintenance.lzma',
"Baked Goods Monster's 101 Types of Baked Goods.pdf"]
Q3)删除所有破折号,除非被单词字符包围
再次成为正则表达式的工作。尝试:
>>> teststring = "Coca-Cola - A History.pdf"
>>> re.sub(r'(\W)-(\W)',r'\1\2',teststring)
'Coca-Cola A History.pdf'
这将删除未被“单词字符”\w
包围的任何短划线,松散地定义为任何字母数字字符,任何数字或下划线。 \W
匹配非字符,即<{>> 与\w
匹配的任何内容。
1)\w
依赖于语言环境:如果您的文件名是俄语,那么西里尔字符也将被视为“单词字符”。
注意:
2)正则表达式实际匹配三个字符 - 替换字符串中的\1
和\2
用于将两个字符放回短划线的两侧。 (参见:“反向引用”。)
3)注意使用原始字符串r"..."
而不是普通字符串"..."
。这是为了防止Python在正则表达式中修改反斜杠。
编辑:这是一个(未经测试的)示例,说明如何将文件名分别处理到扩展名。请注意,我已将所有繁重的工作移动到单独的功能中,而不是使用列表推导。
列表理解对于替换执行一两件事的循环是优雅的,但我个人觉得嵌套列表理解很难阅读。请记住,长度超过80个字符的行是代码气味的指示。
import os, shutil, re
def rename_file (original_filename):
name, extension = os.path.splitext(original_filename)
#remove one or more dashes, surrounded by non-word characters.
modified_name = re.sub(r"(\W)-+(\W)",r"\1\2",name)
new_filename = modified_name + extension
try:
# moves files or directories (recursively)
shutil.move(original_filename, new_filename)
except shutil.Error:
print ("Couldn't rename file %(original_filename)s!" % locals())
target_dir = r"/home/trinity/nmap"
targets = os.listdir(target_dir)
[rename_file(f) for f in targets]