Replace Words in Files or Strings using Python

Preface

I’m a Network Engineer learning Python, and these are purely my notes. I’m not an expert by any means. Feel free to use any of these examples and improve upon them. Feel free to call me out where things can be done better.

Onward

A common task I need to do is replace words in a file with something else. For example:

hostname $hostname
interface Gig0/1
 ip address $ip 255.255.255.252

Where $hostname and $ip should be variables that needs replacing. This post looks at how to accomplish this on the Python interpretor, and via a script file using a Python function.

To keep things relatively simple, I’m only going to perform the replacement on a single file, using a single set of attributes.

Interpretor

Hop into Python

$ python
Python 2.7.9 (default, Dec 15 2014, 10:01:34) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 

First, I’ll open a text file as ‘t‘ and read it into a string called ‘tempstr

>>> t = open('example_template.txt', 'r')
>>> tempstr = t.read()
>>> t.close()

Let’s take a look at this string:

>>> print tempstr
Your hostname is:     $hostname
Your IP address is:   $ip
Did this work?        $answer

The goal is to replace the words starting with a dollar sign ($) with something else. Note that I’m using dollar signs because it makes it easy when doing a find replace. This is not required.

Next I’ll create a dictionary of key/value pairs to be used when replacing variables.  We’ll call this dictionary “device_values

>>> device_values = {
...     '$hostname': 'overlaid-router',
...     '$ip': '169.254.66.6',
...     '$answer': 'yes',
... }

You can see the keys are specified with a dollar sign ($) in front of them. Remember, this has nothing to do with Python, this is simply how I chose to name these keys so they line up with the words I’ll be replacing in my template file.

Now we need to search our string ‘tempstr‘ for the keys found in device_values and replace them with the corresponding values. To accomplish this, we’ll iterate through our dictionary and use the .replace method.

Our current string:

>>> print tempstr
Your hostname is:     $hostname
Your IP address is:   $ip
Did this work?        $answer

Look at each key/value pair in the dictionary and update the tempstr string with the matching key/values

>>> for key,val in device_values.items():
...     tempstr = tempstr.replace(key,val)
... 

Our new string:

>>> print tempstr
Your hostname is:     overlaid-router
Your IP address is:   169.254.66.6
Did this work?        yes

Perfect!

What is .items?

In case you’re curious, the .items method above returns a list of the dictionaries key/value pairs.  Actually, they’re tuples, not dictionaries, but in this case serve the same purpose.  Tuples cannot be changed, unlike dictionaries, but we’re not doing any changing here, just reading.  

This is required when iterating through a dictionary. You can see the difference here between a simple print of the dictionary and a print of the dictionary items.  Notice {} for the dictionary and [()] for the list [] of tuples ().

>>> device_values
{'$ip': '169.254.66.6', '$answer': 'yes', '$hostname': 'overlaid-router'}
>>> device_values.items()
[('$ip', '169.254.66.6'), ('$answer', 'yes'), ('$hostname', 'overlaid-router')]

Python Function to Replace Words

This function will take in two variables: base_text string and device_values dictionary. It will iterate through the dictionary just like the example above and replace words (keys) found in the base_text with corresponding words (values) from the dictionary.

def replace_words(base_text, device_values):
	for key, val in device_values.items():
		base_text = base_text.replace(key, val)
	return base_text

The dictionary and string are derived via the same means as the first example.

t = open('example_template.txt', 'r')
tempstr = t.read()
t.close()

device_values = {
    '$hostname': 'overlaid-router',
    '$ip': '169.254.66.6',
    '$answer': 'yes',
}

The only difference is how we send these to our function for processing. tempstr will go in as the base_text argument and device will go in as the device_values argument.

>>> output = replace_words(tempstr, device)

>>> print output
Your hostname is:     overlaid-router
Your IP address is:   169.254.66.6
Did this work?        yes

As a Python script

The .py script below will ask you for three variables. It will open a template file and perform a find and replace, saving a new file called output.txt to your directory.

#!/usr/bin/env python
# This is a simple Python function that will open a text file and perform a find/replace, and save to a new text file.

def replace_words(base_text, device_values):
	for key, val in device_values.items():
		base_text = base_text.replace(key, val)
	return base_text

# Here I'll create an empty dictionary, and prompt the user to enter in the values

device = {}

device["$hostname"] = raw_input("\nHostname: ")
device["$ip"] = raw_input("\nIP Address: ")
device["$answer"] = raw_input("\nDo you like Python? ")

# Open your desired file as 't' and read the lines into string 'tempstr'

t = open('example_template.txt', 'r')
tempstr = t.read()
t.close()


# Using the "replace_words" function, we'll pass in our tempstr to be used as the base, 
# and our device_values to be used as replacement.  

output = replace_words(tempstr, device)

# Write out the new config file

fout = open('output.txt', 'w')
fout.write(output)
fout.close()

Let’s try it out. Notice I only have 2 files in this directory – my script and the example template

$ ls -l
total 16
-rw-r--r--@ 1 vosx  staff    87B Jan 28 17:28 example_template.txt
-rw-r--r--@ 1 vosx  staff   958B Jan 28 19:04 replace_words.py

Run the replace_words script

$ python replace_words.py

Hostname: overlaid-router

IP Address: 1.1.1.1

Do you like Python? yep

I now have a new file

$ ls -l
total 24
-rw-r--r--@ 1 vosx  staff    87B Jan 28 17:28 example_template.txt
-rw-r--r--@ 1 vosx  staff    93B Jan 28 19:06 output.txt
-rw-r--r--@ 1 vosx  staff   958B Jan 28 19:04 replace_words.py

Let’s take a look

$ more output.txt
Your hostname is:     overlaid-router
Your IP address is:   1.1.1.1
Did this work?        yep

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s