ActiveState Code

Recipe 52250: Search and replace text in a file.


A simple text search and replace program.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
import os, sys
usage = "usage: %s search_text replace_text [infile [outfile]]" %         os.path.basename(sys.argv[0])

if len(sys.argv) < 3:
    print usage
else:
    stext = sys.argv[1]
    rtext = sys.argv[2]
    input = sys.stdin
    output = sys.stdout
    if len(sys.argv) > 3:
        input = open(sys.argv[3])
    if len(sys.argv) > 4:
        output = open(sys.argv[4], 'w')
    for s in input.xreadlines():
        output.write(s.replace(stext, rtext))


  # For older versions of Python (1.5.2 and earlier) import
  # the string module and replace the last two lines with:
  #
  # for s in input.readlines():
  #     output.write(string.replace(s, stext, rtext))

Discussion

Perhaps this is too simple to be included as a cookbook entry, but it's a frequently asked question. Maybe teachers will stop assigning it as a homework problem. ;-)

Comments

  1. 1. At 3:36 a.m. on 16 jan 2002, Adam Krieg said:

    Slight Mods. This code as is will not work. The main problem is that the output file object is not closed, so nothing actually gets written to the file. Also xreadlines is not a method of the file object (at least not in Jython, where I tested this). Anyway, give this one a go:

    #!/usr/bin/env python
    import os, sys, xreadlines
    usage = "usage: %s search_text replace_text [infile [outfile]]" %         os.path.basename(sys.argv[0])
    
    if len(sys.argv) &lt; 3:
            print usage
    else:
            stext = sys.argv[1]
            rtext = sys.argv[2]
            input = sys.stdin
            output = sys.stdout
            print "There are %s args " %len(sys.argv)
            if len(sys.argv) &gt; 3:
                input = open(sys.argv[3])
            if len(sys.argv) &gt; 4:
                output = open(sys.argv[4], 'w')
            print "output = ",output
            for s in xreadlines.xreadlines(input):
            print "s= ",s
                output.write(s.replace(stext, rtext))
            if len(sys.argv)&gt; 3:
            input.close()
            if len(sys.argv) &gt; 4:
                output.close()
    
  2. 2. At 5:07 a.m. on 5 jan 2006, Jani Peki said:

    xreadlines is deprecated. Since xreadlines is deprecated the solution should look like this:

    #!/usr/bin/python
    import os, sys
    usage = "usage: %s search_text replace_text [infile [outfile]]" %         os.path.basename(sys.argv[0])
    
    if len(sys.argv) &lt; 3:
           print usage
    
    else:
            stext = sys.argv[1]
            rtext = sys.argv[2]
            input = sys.stdin
            output = sys.stdout
            print "There are %s args " %len(sys.argv)
    
            if len(sys.argv) > 3:
                    input = open(sys.argv[3])
    
            if len(sys.argv) > 4:
                    output = open(sys.argv[4], 'w')
    
            for s in input:
                    output.write(s.replace(stext, rtext))
    
            if len(sys.argv)> 3:
                input.close()
                if len(sys.argv) > 4:
                        output.close()
    
  3. 3. At 10:39 a.m. on 8 jun 2007, Alex Manus said:

    None of these work. Actually, all of these examples are wrong, s is not defined anywhere in the script and the replace method requires 3 arguments.

  4. 4. At 6:45 a.m. on 26 sep 2007, Daniel Eggleston said:

    Actually. You are wrong... s is declared in the for loop where it is used, and the third argument to replace is optional.

  5. 5. At 10:16 p.m. on 3 sep 2009, Shawn Clark said:

    great recipe, it has been years since I did Python so I appreciate it!

Sign in to comment