Найти строку в файле python

How to search for a string in text files?

I want to check if a string is in a text file. If it is, do X. If it’s not, do Y. However, this code always returns True for some reason. Can anyone see what is wrong?

def check(): datafile = file('example.txt') found = False for line in datafile: if blabla in line: found = True break check() if True: print "true" else: print "false" 

13 Answers 13

The reason why you always got True has already been given, so I’ll just offer another suggestion:

If your file is not too large, you can read it into a string, and just use that (easier and often faster than reading and checking line per line):

with open('example.txt') as f: if 'blabla' in f.read(): print("true") 

Another trick: you can alleviate the possible memory problems by using mmap.mmap() to create a «string-like» object that uses the underlying file (instead of reading the whole file in memory):

import mmap with open('example.txt') as f: s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) if s.find('blabla') != -1: print('true') 

NOTE: in python 3, mmaps behave like bytearray objects rather than strings, so the subsequence you look for with find() has to be a bytes object rather than a string as well, eg. s.find(b’blabla’) :

#!/usr/bin/env python3 import mmap with open('example.txt', 'rb', 0) as file, \ mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as s: if s.find(b'blabla') != -1: print('true') 

You could also use regular expressions on mmap e.g., case-insensitive search: if re.search(br'(?i)blabla’, s):

The second solution does not give the same results as ‘blabla’ in open(‘example.txt’).read() in my python 2.7

Strange, it does work with s.find(‘blabla’) (check for -1). I could swear it used to work with in as well. But it seems now that in only works for single characters.

if ‘blabla’ in open(‘example.txt’).read(): print «true» ==> How can we close example.txt file in this case ?

@begueradj: about the mmap solution: you should use the find() method (see previous comments), I’ve updated the answer accordingly.

open should generally be encapsulated in a with statement: with open(file_name) as fl: return text in fl.read()

Читайте также:  What is solid in css

As Jeffrey Said, you are not checking the value of check() . In addition, your check() function is not returning anything. Note the difference:

def check(): with open('example.txt') as f: datafile = f.readlines() found = False # This isn't really necessary for line in datafile: if blabla in line: # found = True # Not necessary return True return False # Because you finished the search without finding 

Then you can test the output of check() :

if check(): print('True') else: print('False') 

Here’s another way to possibly answer your question using the find function which gives you a literal numerical value of where something truly is

in find write the word you want to find and ‘file’ stands for your file name

This always happens because True is always True.

You want something like this:

if check(): print "true" else: print "false" 

I see, it works now. Seems a bit weird to me though, this means that Python says «a module is True, unless stated otherwise». So if I’d make an empty module, it’d always be true? Interesting 🙂

No, not at all — nothing to do with modules. You were simply checking whether True was true, which it is.

I made a little function for this purpose. It searches for a word in the input file and then adds it to the output file.

def searcher(outf, inf, string): with open(outf, 'a') as f1: if string in open(inf).read(): f1.write(string) 
  • outf is the output file
  • inf is the input file
  • string is of course, the desired string that you wish to find and add to outf.

Your check function should return the found boolean and use that to determine what to print.

def check(): datafile = file('example.txt') found = False for line in datafile: if blabla in line: found = True break return found found = check() if found: print "true" else: print "false" 

the second block could also be condensed to:

if check(): print "true" else: print "false" 

All the above answers are dramatically FALSE except yours. I spent half a day to guess what is happening with the answer they validated while it is totally WRONG. Only yours worked for me

  1. Your function does not return anything; a function that does not explicitly return anything returns None (which is falsy)
  2. True is always True — you are not checking the result of your function
def check(fname, txt): with open(fname) as dataf: return any(txt in line for line in dataf) if check('example.txt', 'blabla'): print "true" else: print "false" 

How to search the text in the file and Returns an file path in which the word is found (Как искать часть текста в файле и возвращять путь к файлу в котором это слово найдено)

import os import re class Searcher: def __init__(self, path, query): self.path = path if self.path[-1] != '/': self.path += '/' self.path = self.path.replace('/', '\\') self.query = query self.searched = <> def find(self): for root, dirs, files in os.walk( self.path ): for file in files: if re.match(r'.*?\.txt$', file) is not None: if root[-1] != '\\': root += '\\' f = open(root + file, 'rt') txt = f.read() f.close() count = len( re.findall( self.query, txt ) ) if count > 0: self.searched[root + file] = count def getResults(self): return self.searched 
# -*- coding: UTF-8 -*- import sys from search import Searcher path = 'c:\\temp\\' search = 'search string' if __name__ == '__main__': if len(sys.argv) == 3: # создаем объект поисковика и передаем ему аргументы Search = Searcher(sys.argv[1], sys.argv[2]) else: Search = Searcher(path, search) # начать поиск Search.find() # получаем результат results = Search.getResults() # выводим результат print 'Found ', len(results), ' files:' for file, count in results.items(): print 'File: ', file, ' Found entries:' , count 

Источник

Читайте также:  Создание сервера на python django

Поиск строк в файле

подстроку for example она не найдет. Каким образом можно осуществить поиск подстрок, расположенных на разных строках в файле?

3 ответа 3

Чтобы найти фразы такие как «for example» в файле, не обращая внимание на вид и количество пробелов между словами, можно нормализировать пробелы в файле и после этого найти строки, которые присутствуют в тексте:

def find_phrases(filename, phrases): with open(filename) as file: text = ' '.join(file.read().split()) # normalize whitespace return filter(text.__contains__, phrases) # return phrases themselves 

Если файл целиком в память не умещается и чтобы не пробегать целый файл заново в поисках каждой фразы, можно регулярные выражения использовать на mmap :

import mmap import re from contextlib import closing def find_phrases(filename, phrases): # match the longest phrases literally ignoring whitespace pattern = '|'.join(['\s+'.join(map(re.escape, p.split())) for p in sorted(phrases, key=len, reverse=True)]) with open(filename, 'r+b', 0) as f, \ closing(mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)) as s: return re.findall(pattern, s) # return matched strings from the file 
print find_phrases('input.txt', ['simple', 'for example']) # -> ['simple', 'for\nexample'] 

mmap позволяет рассматривать файл как байтовую строку, продолжая работать даже для файлов, которые больше доступной памяти. Регулярные выражения позволяют искать сразу все входные фразы одновременно ( a|b|c вид regex).

В зависимости от того что конкретно хочется найти: фиксированные строки, учитывая пробел/игнорируя, целые слова/подстроки, с учётом регистра/без, размера файла, количества и размера отдельных строк итд., могут существовать более эффективные строковые алгоритмы, к примеру алгоритм Ахо-Корасика или с использованием массивов суффиксов, итд.

Источник

Python. Поиск строки в файле python

Есть 2 файла order_fix.txt и listdir.txt необходимо проверить каждую строку из файла listdir.txt проверить на наличие такой же строки в order_fix.txt Написал такой скрипт:

end_list = open('end_list.txt','w') listdir = open('listdir.txt') order = open('order_fix.txt') for line in listdir.readlines(): if line in open('order_fix.txt').read(): end_list.write(line) 

но он выполняется очень долго при ~2kk строк в файле listdir.txt больше 5ч. Есть какой то вариант что бы ускорить этот процесс?

Читайте также:  Делаем страницу на javascript

1 ответ 1

end_list = open('end_list.txt','w') listdir = open('listdir.txt') order_set = set(open('order_fix.txt').readlines()) for line in listdir.readlines(): if line in order_set: end_list.write(line) 

У вас для каждой строки в listdir, вы заново вычитываете весь order_fix. Но чтение с диска — достаточно тяжёлая операция. Поэтому там, где возможно, нужно стараться вычитывать файл только один раз в оперативную память и работать с данными уже в памяти.

Кроме этого, поиск вхождения гораздо быстрее производится в set , чем в списке, поэтому если нужно много и активно искать по большому списку, лучше построить из него один раз set , и искать уже в нём.

PS: Напишите, пожалуйста, насколько быстрее мой код работает по сравнению с вашим, мне любопытно ))

UPD: Ещё не вижу в вашем коде, где у вас выполняется закрытие файлов. Вы его выполняете? Если нет, то файлы всегда стоит закрывать после того, как закончили работу с ними. А лучше вообще всюду, где это возможно, работать с файлами только при помощи менеджера контекста.

Источник

Оцените статью