Nathan Lim
Nathan Lim

Reputation: 45

Search and replace string under specific line

How can I do a search AND REPLACE a string. To be more specific.

I have a text file with

SAMPLE  
AB  
CD  
..  
TYPES  
AB  
QP  
PO  
..  
RUNS  
AB  
DE  
ZY 

I want to replace AB with XX, only under lines SAMPLE and RUNS. I've already tried multiple ways of using replace(). I tried something like

if 'SAMPLE' in line:
    f1.write(line.replace('testsample', 'XX'))
if 'RUNS' in line:
    f1.write(line.replace('testsample', 'XX'))

and that didn't work.

Upvotes: 0

Views: 1022

Answers (3)

jfs
jfs

Reputation: 414189

A file is an iterator over lines in Python:

for line in file:
    output.write(line) # save as is
    if 'SAMPLE' in line or 'RUNS' in line:
       line = next(file, "") # move to the next line
       output.write(line.replace('AB', 'XX')) # save replacing AB with XX

To support SAMPLE/RUNS lines that follows another SAMPLE/RUNS line e.g.:

SAMPLE
SAMPLE
AB

you could:

for line in file:
    output.write(line) # save as is
    while 'SAMPLE' in line or 'RUNS' in line:
       line = next(file, "") # move to the next line
       output.write(line.replace('AB', 'XX')) # save replacing AB with XX

Upvotes: 3

Mike Müller
Mike Müller

Reputation: 85442

Assuming you don't want the lines below SAMPLES replaced and you don't want to replace a line that contains ABC, this would be a bit more robust if your file contains more text per line than the strings you are looking for.

valid_sections = set(('RUNS', 'SAMPLE'))
for raw_line in fobj_in:
    clean_line = raw_line.strip()
    if clean_line in valid_sections:
        fobj_out.write(raw_line)
        raw_line = next(fobj_in)
        clean_line = raw_line.strip()
        if clean_line == 'AB':
            fobj_out.write(raw_line.replace('AB', 'XX'))
        else:
            fobj_out.write(raw_line)
    else:
        fobj_out.write(raw_line)

Upvotes: 1

kirelagin
kirelagin

Reputation: 13616

The easiest way will be to iterate your file line by line, and each time you see a SAMPLE or RUNS line to save a flag meaning “the previous line was the one I was looking for”. Any other line will reset this flag. Now on every iteration you check if the flag was set during the previous iteration, and if it was you do your .replace thing.

Upvotes: 2

Related Questions