有条件地复制 python 中的文件
Conditional copying of files in python
所以我试图将文件复制到另一个目录,如果它们的文件名以与我的列表值相同的 4 位 ID 开头。
我要么将错误的数据写入文件,要么什么都没有。
我目前拥有的:
import shutil
import os
ok_ids = [5252,
8396,
8397,
8397,
8556,
8004,
6545,
6541,
4392,
4392,
6548,
1363,
1363,
1363,
8489,
8652,
1368,
1368]
source = os.listdir("/Users/amm/Desktop/mypath1/")
destination = "/Users/amm/Desktop/mypath2/"
for files in source:
for x in ok_ids:
if files[:4] == x:
shutil.copy(files,destination)
else:
print("not working")
我正在尝试复制的文件示例,即 source
0000_051123_192805.txt
0000_051123_192805.txt
8642_060201_113220.txt
8652_060204_152839.txt
8652_060204_152839.txt
309-_060202_112353.txt
x104_051203_064013.txt
destination
目录为空
一些重要的事情:ok_ids
不包含不同的值,但我希望程序将列表视为包含不同的值。例如 8397
在 ok_ids
列表中出现两次,并且不需要在 ok_ids
循环中迭代两次(它是一个非常长的列表,我不喜欢编辑)。 source
通常也可以包含重复的 ID,使用上面的示例这些是 0000
、8652
,但文件名的其余部分不同。
所以总而言之...如果 0000
在我的 ok_ids
列表中并且在我的 source
目录中有以 0000
开头的文件名那么我想复制他们进入我的 destination
文件夹。
我考虑过使用 .startswith
,但使用列表作为参数并不令人满意,即使我将它转换为元组然后转换为 str。任何帮助都会很棒。
更新
这不起作用的原因可能是某些 ID 包含连字符吗?而其他人以 char x
而不是 int 值开头?
前 4 个值是 ID,例如这些仍然有效:
309-_060202_112353.txt
x104_051203_064013.txt
这应该有效:
for file in source:
for x in set(ok_ids):
if file.startswith(str(x)):
shutil.copy(file, destination)
使用set()
使数字唯一,使用str()
转换为字符串。所以你可以将列表预处理成一个集合以获得更好的性能。
或者更好的是,考虑到您的命名限制:
if int(file.split("_")[0]) in ok_ids:
为什么你的代码不起作用?
if files[:4] == x:
您将 str
与 int
进行比较,直觉上,它始终为 False。
import os
import shutil
for root, dirs, files in os.walk("/Users/amm/Desktop/mypath1/"):
for file in files:
try:
if int(file[:4]) in ok_ids:
shutil.copy(file,destination)
except:
pass
这对我有用。唯一的问题是它会抓取同一目录中的所有文件夹。
你的代码对我有用 str(x)
而不是 x
。
尝试使用它来查看每个文件的作用:
for files in source:
for x in ok_ids:
if files[:4] == str(x):
print("File '{}' matched".format(files))
break
else:
print("File '{}' not matched".format(files))
或者,将 ok_ids
中的所有项目转换为字符串,然后查看生成的结果:
ok_ids = [str(id) for id in ok_ids]
files_matched = [file for file in source if file[:4] in ok_ids]
files[:4] == x
永远不可能为真,因为 x
是一个整数而 files[:4]
是一个字符串。 没关系 如果字符串 表示 x
匹配:
>>> 123 == '123'
False
I've looked at using .startswith
but its not happy using a list as the argument even if i cast it to a tuple and then a str. Any help would be amazing.
这可以说是解决问题的最佳方法,但您不仅需要一个元组 - 您还需要 个人 ID 值 为字符串。您无法对影响 元素 .
的 ok_ids
执行 "cast"(它们不是真正的转换)
最简单的方法是首先创建一个元组,并让元组的元素首先是字符串:
ok_ids = (
'5252',
'8396',
# ...
'1368'
)
如果您不控制此数据,可以使用传递给 tuple
的生成器表达式来创建元组:
ok_ids = tuple(str(x) for x in ok_ids)
所以我试图将文件复制到另一个目录,如果它们的文件名以与我的列表值相同的 4 位 ID 开头。 我要么将错误的数据写入文件,要么什么都没有。
我目前拥有的:
import shutil
import os
ok_ids = [5252,
8396,
8397,
8397,
8556,
8004,
6545,
6541,
4392,
4392,
6548,
1363,
1363,
1363,
8489,
8652,
1368,
1368]
source = os.listdir("/Users/amm/Desktop/mypath1/")
destination = "/Users/amm/Desktop/mypath2/"
for files in source:
for x in ok_ids:
if files[:4] == x:
shutil.copy(files,destination)
else:
print("not working")
我正在尝试复制的文件示例,即 source
0000_051123_192805.txt
0000_051123_192805.txt
8642_060201_113220.txt
8652_060204_152839.txt
8652_060204_152839.txt
309-_060202_112353.txt
x104_051203_064013.txt
destination
目录为空
一些重要的事情:ok_ids
不包含不同的值,但我希望程序将列表视为包含不同的值。例如 8397
在 ok_ids
列表中出现两次,并且不需要在 ok_ids
循环中迭代两次(它是一个非常长的列表,我不喜欢编辑)。 source
通常也可以包含重复的 ID,使用上面的示例这些是 0000
、8652
,但文件名的其余部分不同。
所以总而言之...如果 0000
在我的 ok_ids
列表中并且在我的 source
目录中有以 0000
开头的文件名那么我想复制他们进入我的 destination
文件夹。
我考虑过使用 .startswith
,但使用列表作为参数并不令人满意,即使我将它转换为元组然后转换为 str。任何帮助都会很棒。
更新
这不起作用的原因可能是某些 ID 包含连字符吗?而其他人以 char x
而不是 int 值开头?
前 4 个值是 ID,例如这些仍然有效:
309-_060202_112353.txt
x104_051203_064013.txt
这应该有效:
for file in source:
for x in set(ok_ids):
if file.startswith(str(x)):
shutil.copy(file, destination)
使用set()
使数字唯一,使用str()
转换为字符串。所以你可以将列表预处理成一个集合以获得更好的性能。
或者更好的是,考虑到您的命名限制:
if int(file.split("_")[0]) in ok_ids:
为什么你的代码不起作用?
if files[:4] == x:
您将 str
与 int
进行比较,直觉上,它始终为 False。
import os
import shutil
for root, dirs, files in os.walk("/Users/amm/Desktop/mypath1/"):
for file in files:
try:
if int(file[:4]) in ok_ids:
shutil.copy(file,destination)
except:
pass
这对我有用。唯一的问题是它会抓取同一目录中的所有文件夹。
你的代码对我有用 str(x)
而不是 x
。
尝试使用它来查看每个文件的作用:
for files in source:
for x in ok_ids:
if files[:4] == str(x):
print("File '{}' matched".format(files))
break
else:
print("File '{}' not matched".format(files))
或者,将 ok_ids
中的所有项目转换为字符串,然后查看生成的结果:
ok_ids = [str(id) for id in ok_ids]
files_matched = [file for file in source if file[:4] in ok_ids]
files[:4] == x
永远不可能为真,因为 x
是一个整数而 files[:4]
是一个字符串。 没关系 如果字符串 表示 x
匹配:
>>> 123 == '123'
False
I've looked at using
.startswith
but its not happy using a list as the argument even if i cast it to a tuple and then a str. Any help would be amazing.
这可以说是解决问题的最佳方法,但您不仅需要一个元组 - 您还需要 个人 ID 值 为字符串。您无法对影响 元素 .
的ok_ids
执行 "cast"(它们不是真正的转换)
最简单的方法是首先创建一个元组,并让元组的元素首先是字符串:
ok_ids = (
'5252',
'8396',
# ...
'1368'
)
如果您不控制此数据,可以使用传递给 tuple
的生成器表达式来创建元组:
ok_ids = tuple(str(x) for x in ok_ids)