Skip to content Skip to sidebar Skip to footer

Python Equivalent To Sed

Is there a way, without a double loop to accomplish what the following sed command does Input: Time Banana spinach turkey sed -i '/Banana/ s/$/Toothpaste/' file Output: Time Banan

Solution 1:

Using re.sub():

newstring = re.sub('(Banana)', r'\1Toothpaste', oldstring)

This catches one group (between first parentheses), and replaces it by ITSELF (the \number part) followed by a desired suffix. It is needed to use r'' (raw string) so that the escape is correctly interpreted.

Solution 2:

A late comer to the race, here is my implementation for sed in Python:

import re
import shutil
from tempfile import mkstemp


defsed(pattern, replace, source, dest=None, count=0):
    """Reads a source file and writes the destination file.

    In each line, replaces pattern with replace.

    Args:
        pattern (str): pattern to match (can be re.pattern)
        replace (str): replacement str
        source  (str): input filename
        count (int): number of occurrences to replace
        dest (str):   destination filename, if not given, source will be over written.        
    """

    fin = open(source, 'r')
    num_replaced = count

    if dest:
        fout = open(dest, 'w')
    else:
        fd, name = mkstemp()
        fout = open(name, 'w')

    for line in fin:
        out = re.sub(pattern, replace, line)
        fout.write(out)

        if out != line:
            num_replaced += 1if count and num_replaced > count:
            breaktry:
        fout.writelines(fin.readlines())
    except Exception as E:
        raise E

    fin.close()
    fout.close()

    ifnot dest:
        shutil.move(name, source) 

examples:

sed('foo', 'bar', "foo.txt") 

will replace all 'foo' with 'bar' in foo.txt

sed('foo', 'bar', "foo.txt", "foo.updated.txt")

will replace all 'foo' with 'bar' in 'foo.txt' and save the result in "foo.updated.txt".

sed('foo', 'bar', "foo.txt", count=1)

will replace only the first occurrence of 'foo' with 'bar' and save the result in the original file 'foo.txt'

Solution 3:

If you are using Python3 the following module will help you: https://github.com/mahmoudadel2/pysed

wget https://raw.githubusercontent.com/mahmoudadel2/pysed/master/pysed.py

Place the module file into your Python3 modules path, then:

import pysed
pysed.replace(<Oldstring>, <ReplacementString>, <TextFile>)
pysed.rmlinematch(<Unwantedstring>, <TextFile>)
pysed.rmlinenumber(<UnwantedLineNumber>, <TextFile>)

Solution 4:

You can actually call sed from python. Many ways to do this but I like to use the sh module. (yum -y install python-sh)

The output of my example program is a follows.

[me@localhost sh]$ cat input 
Time
Banana
spinich
turkey
[me@localhost sh]$ python test_sh.py 
[me@localhost sh]$ cat input 
Time
Toothpaste
spinich
turkey
[me@localhost sh]$ 

Here is test_sh.py

import sh

sh.sed('-i', 's/Banana/Toothpaste/', 'input')

This will probably only work under LINUX.

Solution 5:

It's possible to do this using tmp file with low system requirements and only one iteration without copying whole file into the memory:

#/usr/bin/python
import tempfile
import shutil
import os

newfile = tempfile.mkdtemp()
oldfile = 'stack.txt'

f = open(oldfile)
n = open(newfile,'w')

for i in f:
        if i.find('Banana') == -1:
                n.write(i)
                continue

        # Last row
        if i.find('\n') == -1:
                i += 'ToothPaste'else:
                i = i.rstrip('\n')
                i += 'ToothPaste\n'

        n.write(i) 

f.close()
n.close()

os.remove(oldfile)
shutil.move(newfile,oldfile)

Post a Comment for "Python Equivalent To Sed"