How to do sed like text replace with python?
massedit.py (http://github.com/elmotec/massedit) does the scaffolding for you leaving just the regex to write. It's still in beta but we are looking for feedback.
python -m massedit -e "re.sub(r'^# deb', 'deb', line)" /etc/apt/sources.list
will show the differences (before/after) in diff format.
Add the -w option to write the changes to the original file:
python -m massedit -e "re.sub(r'^# deb', 'deb', line)" -w /etc/apt/sources.list
Alternatively, you can now use the api:
>>> import massedit
>>> filenames = ['/etc/apt/sources.list']
>>> massedit.edit_files(filenames, ["re.sub(r'^# deb', 'deb', line)"], dry_run=True)
python search/replace regex with sed-like expression
My first thoughts were just to split it by /
and pass it as args to re.sub
.
Turns out this is rather complicated and as I'm pretty sure its not bulletproof, so I give you this as a starting point.
Thing is, what if we want to deal with slashes, as in replace slashes with backslashes. Then the sed expression will be
's/\\/\//g'
I have to split it by slash that is not preceded by backlash
_, pattern, repl, options = re.split(r'(?<!\\)/', sed)
To make it more complicated, the shash can be preceded by two backslashes, so:
_, pattern, repl, options = re.split(r'(?<![^\\]\\)/', sed)
And re.sub
will look like
re.sub(pattern, repl, s, count='g' not in options)
Ups, no, in Python, slash doesn't have to be escaped, so:
re.sub(pattern, re.sub(r'\\/', '/', repl), s, count='g' not in options)
>>> import re
>>> s = r'\some\windows\path'
>>> sed = r's/\\/\//g'
>>> _, pattern, repl, options = re.split(r'(?<![^\\]\\)/', sed)
>>> re.sub(pattern, re.sub(r'\\/', '/', repl), s, count='g' not in options)
'/some/windows/path'
Replace a string in a python script and execute the script
You sound like you know how to use commandline arguments, but just for the sake of completion, for those who read this question in the future and are not sure how to go about using command line arguments with python:
One easy quick way to receive commandline arguments in your code is to use the argv
property of the sys
module which is a list that contains all arguments sent to the script. When a python file is called, the first argument captured by sys.argv
is the name of the script itself. Any commandline arguments are captured afterwards:
import sys
arguments = sys.argv
# make sure user really sent an argument, or else set it to some default value
if len(arguments)>1:
desired_string = arguments[1]
else:
desired_string = "Some_default_value"
How to search and replace text in a file?
fileinput
already supports inplace editing. It redirects stdout
to the file in this case:
#!/usr/bin/env python3
import fileinput
with fileinput.FileInput(filename, inplace=True, backup='.bak') as file:
for line in file:
print(line.replace(text_to_search, replacement_text), end='')
sed to python replace extra delimiters in a
You may read the file line by line, split with tab, and if there are more than 3 items, join the items after the 3rd one with _tab_
:
lines = []
with open('inputfile.txt', 'r') as fr:
for line in fr:
split = line.split('\t')
if len(split) > 3:
tmp = split[:2] # Slice the first two items
tmp.append("_tab_".join(split[2:])) # Append the rest joined with _tab_
lines.append("\t".join(tmp)) # Use the updated line
else:
lines.append(line) # Else, put the line as is
See the Python demo
The lines
variable will contain something like
Mike -3,434.09 testing_tab_testing_tab_123
Mike -3,434.09 testing_tab_256
No operation here
Replace strings and update file using sed from python
To use >
redirection you need to use shell=True
and a single string argument, not a list.
subprocess.call("""sed 's/"A"|"B"|"C"/A|B|C/g' inputfile.txt > outputfile.txt""", shell=True)
How to replace multiple lines in file in Python using sed
You have to create a raw string to prevent python from parsing the input string before passing it on the OS call.
The below example illustrates this
Your input string is
sed -i -e '/NATOMS/c\NATOMS 5 -1.10\n hi\nbye' sedinp.txt
Now assign it to a variable and print it
>>> normalcmd="sed -i -e '/NATOMS/c\NATOMS 5 -1.10\n hi\nbye' sedinp.txt"
>>> print normalcmd
sed -i -e '/NATOMS/c\NATOMS 5 -1.10
hi
bye' sedinp.txt
>>>
As you see, the escape sequences have been parsed.
Now create a raw string.
>>> rawcmd=r"sed -i -e '/NATOMS/c\NATOMS 5 -1.10\n hi\nbye' sedinp.txt"
>>> print rawcmd
sed -i -e '/NATOMS/c\NATOMS 5 -1.10\n hi\nbye' sedinp.txt
>>>
You can see that the escape sequences are not parsed.
Now use it in the os call.
>>> os.system(rawcmd)
0
>>>
Hope this helps.
Related Topics
Python Ftp Get the Most Recent File by Date
Yes' Reporting Error With Subprocess Communicate()
How to Avoid Having Class Data Shared Among Instances
Switch Between Two Frames in Tkinter
Limiting Floats to Two Decimal Points
How to Put the Legend Outside the Plot
Printing Lists as Tabular Data
What Are the Differences Between Type() and Isinstance()
How to Watch a File For Changes
Python Subprocess.Popen "Oserror: [Errno 12] Cannot Allocate Memory"
Django Server Killed Frequently
Regexp Finding Longest Common Prefix of Two Strings
Get the Cartesian Product of a Series of Lists
Why Does Append() Always Return None in Python
Error: Unable to Find Vcvarsall.Bat
How to Type Hint a Method With the Type of the Enclosing Class
What Is the Purpose of the Return Statement? How Is It Different from Printing