Python writing to file using stdout and fileinput - python

I have the following code, which modifies each line of the file test.tex by making a regular expression substitution.
import re
import fileinput
regex=re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)')
for line in fileinput.input('test.tex',inplace=1):
print regex.sub(r'\3\2\1\4\5',line),
The only problem is that I only want the substitution to apply to certain lines in the file, and there's no way to define a pattern to select the correct lines. So, I want to display each line and prompt the user at the command line, asking whether to make the substitution at the current line. If the user enters "y", the substitution is made. If the user simply enters nothing, the substitution is not made.
The problem, of course, is that by using the code inplace=1 I've effectively redirected stdout to the opened file. So there's no way to show output (e.g. asking whether to make the substitution) to the command line that doesn't get sent to the file.
Any ideas?

The file input module is really for dealing with more than one input file.
You can use the regular open() function instead.
Something like this should work.
By reading the file then resetting the pointer with seek(), we can override the file instead of appending to the end, and so edit the file in-place
import re
regex = re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)')
with open('test.tex', 'r+') as f:
old = f.readlines() # Pull the file contents to a list
f.seek(0) # Jump to start, so we overwrite instead of appending
for line in old:
s = raw_input(line)
if s == 'y':
f.write(regex.sub(r'\3\2\1\4\5',line))
else:
f.write(line)
http://docs.python.org/tutorial/inputoutput.html

Based on the help everyone provided, here's what I ended up going with:
#!/usr/bin/python
import re
import sys
import os
# regular expression
regex = re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)')
# name of input and output files
if len(sys.argv)==1:
print 'No file specified. Exiting.'
sys.exit()
ifilename = sys.argv[1]
ofilename = ifilename+'.MODIFIED'
# read input file
ifile = open(ifilename)
lines = ifile.readlines()
ofile = open(ofilename,'w')
# prompt to make substitutions wherever a regex match occurs
for line in lines:
match = regex.search(line)
if match is not None:
print ''
print '***CANDIDATE FOR SUBSTITUTION***'
print '--: '+line,
print '++: '+regex.sub(r'\3\2\1\4\5',line),
print '********************************'
input = raw_input('Make subsitution (enter y for yes)? ')
if input == 'y':
ofile.write(regex.sub(r'\3\2\1\4\5',line))
else:
ofile.write(line)
else:
ofile.write(line)
# replace original file with modified file
os.remove(ifilename)
os.rename(ofilename, ifilename)
Thanks a lot!

Related

Writing a Python 3.9 script to parse a text file and act based on first char of line

I'm new to python and am struggling to figure out how to load a line from a file into a string so I can parse it and act on it. The input text file is a script for a video that will create Amazon Polly mp3 files, based on the text in the file.
The file uses the first character as either an 'A:'(action, ignore),'F:'(filename),'T:'(text for Polly),or '#' (comment, ignore) then followed by string text, For example:
#This example says that the author should move the cursor, then the corresponding Audio
#created from Polly ("Move the cursor to the specified location") is dumped into Move_Cursor.mp3
A:Move the cursor
T:Move the cursor to the specified location
F:Move_Cursor.mp3
#end of example
I've been trying to use the read or readline, but I can't figure out how to take the value returned by those to create a string so I can parse it.
script_file = open(input("Enter the script filename: "),'r')
lines = script_file.readlines()
cnt = 0
for line in lines:
eol = len(line)
print ("line length is: ",eol)
action = line.read #<<THIS IS WHERE I'M HAVING A TYPE ISSUE
print ("action is ",action)
print ("string is ",line)
script_file.close()
Thank you!!!!
Here is a possible solution:
filename = input('Enter the script filename: ')
actions = {'#': 'comment', 'A': 'action', 'T': 'text for polly', 'F': 'filename'}
with open(filename, 'r') as file:
for line in file:
line = line.strip()
lof = len(line)
action = actions.get(line[0])
text = line[1:].lstrip(':')
print(
f'Length of line: {lof}\n'
f' Action: {action}\n'
f' Text: {text}\n'
)
Also I would suggest that for choosing files you use the built-in tkinter module which has a function for displaying the file chooser (it will limit human error in typing out the correct filename):
from tkinter import Tk, filedialog
Tk().withdraw()
filename = filedialog.askopenfilename()
Or just skip the filename part:
from tkinter import Tk, filedialog
Tk().withdraw()
with filedialog.askopenfile(mode='r') as file:
For those of you interested. Being new to python, I got sloppy with my spaces and tabs. My issue with the code, even though it was pointing to a syntax error on a line that should have passed, was that I was mixing spaces and tabs in my indentation, so it lost it's mind. BUT, THANK YOU for everyone that answered, as it did help me figure out a better way of doing what I was trying to do, and of course, I did find a missing ':' also.
You can check the first character of every line with:
action = line[0]

delete a user defined text from a text file in python

def Delete_con():
contact_to_delete= input("choose name to delete from contact")
to_Delete=list(contact_to_delete)
with open("phonebook1.txt", "r+") as file:
content = file.read()
for line in content:
if not any(line in line for line in to_Delete):
content.write(line)
I get zero error. but the line is not deleted. This function ask the user what name he or she wants to delete from the text file.
This should help.
def Delete_con():
contact_to_delete= input("choose name to delete from contact")
contact_to_delete = contact_to_delete.lower() #Convert input to lower case
with open("phonebook1.txt", "r") as file:
content = file.readlines() #Read lines from text
content = [line for line in content if contact_to_delete not in line.lower()] #Check if user input is in line
with open("phonebook1.txt", "w") as file: #Write back content to text
file.writelines(content)
Assuming that:
you want the user to supply just the name, and not the full 'name:number' pair
your phonebook stores one name:number pair per line
I'd do something like this:
import os
from tempfile import NamedTemporaryFile
def delete_contact():
contact_name = input('Choose name to delete: ')
# You probably want to pass path in as an argument
path = 'phonebook1.txt'
base_dir = os.path.dirname(path)
with open(path) as phonebook, \
NamedTemporaryFile(mode='w+', dir=base_dir, delete=False) as tmp:
for line in phonebook:
# rsplit instead of split supports names containing ':'
# if numbers can also contain ':' you need something smarter
name, number = line.rsplit(':', 1)
if name != contact_name:
tmp.write(line)
os.replace(tmp.name, path)
Using a tempfile like this means that if something goes wrong while processing the file you aren't left with a half-written phonebook, you'll still have the original file unchanged. You're also not reading the entire file into memory with this approach.
os.replace() is Python 3.3+ only, if you're using something older you can use os.rename() as long as you're not using Windows.
Here's the tempfile documentation. In this case, you can think of NamedTemporaryFile(mode='w+', dir=base_dir, delete=False) as something like open('tmpfile.txt', mode='w+'). NamedTemporaryFile saves you from having to find a unique name for your tempfile (so that you don't overwrite an existing file). The dir argument creates the tempfile in the same directory as phonebook1.txt which is a good idea because os.replace() can fail when operating across two different filesystems.

how to choose and upload a file in python

I am writing a program where it asks you what text file the user wants to read then it begins to read whatever file name the user inputs. Here is what I have so far:
import sys
import os
import re
#CHOOSE FILE
print "Welcome to the Parsing Database"
raw_input=raw_input("enter file name to parse: ")
#ASSIGN HEADERS AND SEQUENCES
f=open("raw_input", "r")
header=[]
sequence=[]
string=""
for line in f:
if ">" in line and string=="":
header.append(line[:-2])
elif ">" in line and string!="":
sequence.append(string)
header.append(line[:-2])
string=""
else:
string=string+line[:-2]
sequence.append(string)
The first two lines work but then it says it cannot find the file that I inputted to read. Please help! Thanks.
Off the top of my head, I think that f = open("raw_input", "r") needs to be f=open(raw_input, "r"), because you are trying to reference the string contained in the variable raw_input, as opposed to trying to open a file named raw_input. Also you should probably change the name of the variable to something more readable, because raw_input() is a function used in your code as well as a variable, which makes it hard to read. Are there any other specific problems you are having with your code?
f=open("raw_input", "r")
"raw_input" is a plain string. You have to referente to it as raw_input.
Also, there's no lines if you don't use .read() with open() method so you can't parse them. Read lines from a file given from raw_input can be done doing that:
import sys
import os
import re
#CHOOSE FILE
print "Welcome to the Parsing Database"
raw_input_file=raw_input("enter file name to parse: ")
#ASSIGN HEADERS AND SEQUENCES
testfile = open(raw_input_file, "r")
secuence = []
for line in testfile.read().splitlines():
secuence.append(line)
for i in secuence:
print i
testfile.close()

How to check if a file equals a variable in python?

I am a novice with Python I suppose, and I was wondering if there was a way to read a file and then check if user's input equalled that file's text.
I've been trying to create a password program without having to show the password/variable in the program. If there's another way to do this without doing .read() and things (if they don't work) then I would be happy to hear those suggestions!
This should do it:
# The path to the file
filepath = 'thefile.txt'
# This is how you should open files
with open(filepath, 'r') as f:
# Get the entire contents of the file
file_contents = f.read()
# Remove any whitespace at the end, e.g. a newline
file_contents = file_contents.strip()
# Get the user's input
user_input = input('Enter input: ')
if user_input == file_contents:
print('Match!')
else:
print('No match.')

How to print every line from a text file that contains a certain phrase

I have to write a function which can search a txt file for a phrase then print every line that contains the phrase.
def find_phrase(filename,phrase):
for line in open(filename):
if phrase in line:
print line,
That is what I have at the moment and it only prints the first instance.
I have tried your code with a sample script, which goes like this
#sample.py
import sys
print "testing sample"
sys.exit()
when i run your script,
find_phrase('sample.py','sys')
It prints,
import sys
sys.exit().
If this is not your intended output, please share the file you are using.
Below is the pythonic approach. The with statement will safely open the file and handle closing the file when it is done. You can also open multiple files with the "with" statement. How to open a file using the open with statement
def print_found_lines(filename, phrase):
"""Print the lines in the file that contains the given phrase."""
with open(filename, "r") as file:
for line in file:
if phrase in line:
print(line.replace("\n", ""))
# end with (closes file automatically)
# end print_found_lines

Categories

Resources