Jak nalézt řetězec v souboru?

Pokud jde o krátký soubor a stačí pozice v bajtech, pak stačí načíst obsah souboru do řetězcové proměnné a použít její metodu find():

fname = 'soubor.txt'
pattern = 'vzorek'

f = file(fname, 'rb')
content = f.read()
f.close()

index = content.find(pattern)

print index
print '-' * 70

V tomto případě jsem použil binární režim otvírání souboru. Při použití textového režimu se například pod Windows ohlásí chybná pozice, protože se oddělení řádků převede z dvouznakového na jednoznakové.

Pokud by bylo potřeba číst třeba i dlouhý soubor a zjistit číslo řádku a pozici, lze to udělat takto:

fname = 'soubor.txt'
pattern = 'vzorek'

f = file(fname)
lineno = 0
for line in f:
   lineno += 1
   pos = line.find(pattern)
   if pos != -1:
       print lineno, pos
f.close()

print '-' * 70

Čtení souboru utf-8

Většinou (snad) stačí obyčejné čtení, jako u kterékoliv jiného kodovani:

f = file('soubor.txt')
for line in f:
    print line
f.close()

Problém je, že tisk není hezky česky. Stačí tedy převézt z utf-8 do unicode:

f = file('soubor.txt')
for line in f:
    print line.decode("utf-8")
f.close()

Hezčeji se to samé dá provést pomocí modulu codecs:

import codecs
f = codecs.open('soubor.txt', 'rU', 'utf-8')
for line in f:
    print line
f.close()

BOM

Máte-li však soubor s tzv. signaturou BOM na začátku (simulaci v PSPadu můžete provést v Nastavení - Nastavení programu - Program-chování - Identifikační byty v kodování UTF-8), výše uvedený postup vám hází chybu:

UnicodeEncodeError: 'charmap' codec can't encode character u'\ufeff' in position
0: character maps to <undefined>

Jedná se právě o značku BOM, která se nedá převést na tisknutelný tvar. V tomto případě je výhodné použít kodování utf-8-sig:

import codecs
f = codecs.open('soubor.txt', 'rU', 'utf-8-sig')
for line in f:
    print line
f.close()