Python 从目录中所有文件的列表中搜索所有单词,并返回上下文
我有一个关键字列表Python 从目录中所有文件的列表中搜索所有单词,并返回上下文,python,list,Python,List,我有一个关键字列表 Animals = ['dogs' , 'cat' , 'bird' ....] 我有一个包含许多文件的目录,其中可能出现1个或多个关键字 File1.txt “我是一辆车,我去嘟嘟” “我是一只猫,我会喵喵叫” “我是一条狗,我去求爱” File2.txt “我是一只铃铛,我去叮当” “我是一只鸟,我去推特” “我是打印机,我去brrr” 我想搜索目录中的每个文件,并检查我的动物列表中的所有事件。 我想记录文件名、行号、匹配项、行 所需输出示例: File1.t
Animals = ['dogs' , 'cat' , 'bird' ....]
我有一个包含许多文件的目录,其中可能出现1个或多个关键字
File1.txt
- “我是一辆车,我去嘟嘟”
- “我是一只猫,我会喵喵叫”
- “我是一条狗,我去求爱”
- “我是一只铃铛,我去叮当”
- “我是一只鸟,我去推特”
- “我是打印机,我去brrr”
- File1.txt,2,cat,“我是一只猫,我会喵喵叫”
- File1.txt,3,dog,“我是一只狗,我去求爱”
- File2.txt,2,bird,“我是一只鸟,我去推特”
import os
import re
words = ['dog' , 'cat' , 'bird' ]
rx = re.compile('|'.join(words), re.I)
for root, dirs, files in os.walk('C:\\MySearchDirectory\\'):
for filename in files:
if filename.endswith('.txt'):
with open(root + filename) as df:
data = df.read()
for match in rx.finditer(data):
print(filename + ' , ' + str(match) + ' , ' + str(match.span()))
当Python的标准
in
操作符将完成这项工作时,不需要使用正则表达式,IMO:
import os
words = ['dog', 'cat', 'bird']
for root, _, files in os.walk(r'C:\MySearchDirectory'):
for path in filter(lambda p: p.endswith('.txt'), files):
with open(os.path.join(root, path)) as f:
for i, line in enumerate(f.readlines()):
for word in filter(lambda w: w in line, words):
print(f'{path}, {i+1}, {word}, {line.strip()}')
在循环中使用filter
vs列表理解vsif
是一个趣味问题,但在这种情况下,我认为这是最简单的选择,因为它使两个过滤条件(文件需要以.txt
结尾,单词需要出现在行中)一目了然
输出:
File1.txt, 2, cat, "I'm a cat, I go meow"
File1.txt, 3, dog, "I'm a dog, I go woof"
File2.txt, 2, bird, "I'm a bird, I go tweet"
当Python的标准
in
操作符将完成这项工作时,不需要使用正则表达式,IMO:
import os
words = ['dog', 'cat', 'bird']
for root, _, files in os.walk(r'C:\MySearchDirectory'):
for path in filter(lambda p: p.endswith('.txt'), files):
with open(os.path.join(root, path)) as f:
for i, line in enumerate(f.readlines()):
for word in filter(lambda w: w in line, words):
print(f'{path}, {i+1}, {word}, {line.strip()}')
在循环中使用filter
vs列表理解vsif
是一个趣味问题,但在这种情况下,我认为这是最简单的选择,因为它使两个过滤条件(文件需要以.txt
结尾,单词需要出现在行中)一目了然
输出:
File1.txt, 2, cat, "I'm a cat, I go meow"
File1.txt, 3, dog, "I'm a dog, I go woof"
File2.txt, 2, bird, "I'm a bird, I go tweet"
您可以这样做:
from pathlib import Path
def find_occurrences(file, any_word:list) -> list:
occurrences = []
with open(file, 'r') as f:
text = f.read()
lines = text.split('\n')
for line_number, line in enumerate(lines, start=1):
matched_words = [word for word in any_word if word in line]
if matched_words:
occurrence = {
"file": file,
"line_number": line_number,
"line": line,
"matched_words": matched_words
}
occurrences.append(occurrence)
return occurrences
occurrences = []
for file in Path(r"C:\\MySearchDirectory\\").glob("**/*.txt"):
occurrences += find_occurrences(file, any_word=["cat", "dog"])
occurrences
首先,我们循环目录中的所有“.txt”文件,并为每个文件执行函数find\u occurrencess
。这个函数返回事件列表,我们用它更新最终结果。函数本身只读取一个文件,遍历文件的每一行,检查每一行是否包含指定的单词,如果包含指定的单词,则存储到结果中
返回的字典列表的结构如下:
[
{
'file': 'C:\\MySearchDirectory\\subdir\\file1.txt',
'line_number': 5,
'matched_words': ['cat', 'dog'],
'line': 'meau cat, hau hau dog'
},
...
]
如果您需要其他内容,只需调整事件字典即可。请注意,行_编号从1开始。这似乎是本例的目的。您可以按以下方式执行:
from pathlib import Path
def find_occurrences(file, any_word:list) -> list:
occurrences = []
with open(file, 'r') as f:
text = f.read()
lines = text.split('\n')
for line_number, line in enumerate(lines, start=1):
matched_words = [word for word in any_word if word in line]
if matched_words:
occurrence = {
"file": file,
"line_number": line_number,
"line": line,
"matched_words": matched_words
}
occurrences.append(occurrence)
return occurrences
occurrences = []
for file in Path(r"C:\\MySearchDirectory\\").glob("**/*.txt"):
occurrences += find_occurrences(file, any_word=["cat", "dog"])
occurrences
首先,我们循环目录中的所有“.txt”文件,并为每个文件执行函数find\u occurrencess
。这个函数返回事件列表,我们用它更新最终结果。函数本身只读取一个文件,遍历文件的每一行,检查每一行是否包含指定的单词,如果包含指定的单词,则存储到结果中
返回的字典列表的结构如下:
[
{
'file': 'C:\\MySearchDirectory\\subdir\\file1.txt',
'line_number': 5,
'matched_words': ['cat', 'dog'],
'line': 'meau cat, hau hau dog'
},
...
]
如果您需要其他内容,只需调整事件字典即可。请注意,行_编号从1开始。这似乎是本例的意图。不确定最好的方法是什么,因为我不喜欢正则表达式,但您肯定应该使用
glob
overos
来获取文件名,因为它会短得多list\u of_text\u files=glob.glob('C:\\MySearchDirectory\\*.txt')
glob
也是内置的,所以你应该知道。谢谢你的评论,我会尝试用glob重新编写代码,我在搜索时看到了一些关于这方面的东西。如果我不使用正则表达式,我担心我会粗暴地强迫搜索。因此,对于wordSearch列表中的每一个元素,我都要检查每个文件中的每一行;没有办法逃避这个问题(除了使用数据库而不是平面文件)。我不确定这样做的最佳方式是什么,因为我不喜欢正则表达式,但您肯定应该使用glob
overos
来获得文件名,因为它会短得多list\u of_text\u files=glob.glob('C:\\MySearchDirectory\\*.txt')
glob
也是内置的,所以你应该知道。谢谢你的评论,我会尝试用glob重新编写代码,我在搜索时看到了一些关于这方面的东西。如果我不使用正则表达式,我担心我会粗暴地强迫搜索。因此,对于wordSearch列表中的每一个元素,我都要检查每个文件中的每一行;这是无法逃避的(除了使用数据库而不是平面文件)。哇,这真是太棒了。我需要一些时间来理解所有的片段,但这正是我想要的。这真是太有用了。哇,桑怀斯,谢谢你。哇,这真是太棒了。我需要一些时间来理解所有的片段,但这正是我想要的。这是非常有用的。