two for loop in python fileinput - python

cur = mysqlcon.cursor()
sql_select_query = """select name,AES_DECRYPT(passwd, 'hardpass') as passwd from fullusers WHERE id = %s"""
# set variable in query
cur.execute(sql_select_query, (iduser,))
myresult = cur.fetchone()
nameuser = myresult['name']
passuser = myresult['passwd']
psuser = str(passuser,'utf-8')
if mysqlcon:
print ("Connected Successfully")
else:
print ("Connection Not Established")
query = """select * from v_ips WHERE uid = %s"""
cur.execute(query, (iduser,))
data = cur.fetchall()
file_name = '/usr/local/etc/3proxy.cfg'
for line in fileinput.FileInput(file_name,inplace=1):
if 'allow login,'+ nameuser +'' in line:
for x in data:
line = line.rstrip()
line = line.replace(line, line+'\rproxy -n -a -p8989 -i'+ x['ip'] +' -e'+ x['ip'] +'')
It is necessary to add several lines from the database to the file after a certain word, when such a structure is as above, all the data in the file simply disappears, maybe I'm doing something wrong?
for line in fileinput.FileInput(file_name,inplace=1):
if 'allow login,'+ nameuser +'' in line:
line = line.rstrip()
for x in data:
line = line.replace(line, line+'\rproxy -n -a -p8989 -i'+ x['ip'] +' -e'+ x['ip'] +'')
such a structure also deletes all data in the file, swapping the loop occurs just as simply deleting all data

I am not familiar with the fileinput library so this might not be "best practice" by any means, however I got it working at least.
With the test file test_file.txt containing this:
test
test
no
no
test
no
and with the following code:
import fileinput
file_name = "test_file.txt"
for line in fileinput.FileInput(file_name,inplace=1):
if 'test' in line:
print(line.replace(line,"this line has officially been tested"))
else:
print(line, end="")
I got the following result:
this line has officially been tested
this line has officially been tested
no
no
this line has officially been tested
no
For some reason using print within the FileInput block of code prints to the file not stdout.
Additionally it is recommended to use context managers whenever operating on files.
Example:
import fileinput
file_name = "test_file.txt"
with fileinput.FileInput(file_name,inplace=1) as file:
for line in file:
if 'test' in line:
print(line.replace(line,"this line has officially been tested"))
else:
print(line, end="")

Related

Save stdout of fileinput to file

sorry but i'm very new to python, i need a script to search by pattern and replace entire line into a file, i have insert entire script but the problem is after with fileinput...
#!/usr/bin/env python3
import json
import requests
import sys
import fileinput
url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/test'
r = requests.get(url)
accesskey = json.loads(r.content.decode('utf-8'))['AccessKeyId']
secretkey = json.loads(r.content.decode('utf-8'))['SecretAccessKey']
with fileinput.input(files=('./envFile.sh')) as envfile:
for line in envfile:
if line.strip().startswith('export AWS_ACCESS_KEY='):
line = 'AWS_ACCESS_KEY="%s"\n' % (accesskey)
if line.strip().startswith('export AWS_SECRET_KEY='):
line = 'AWS_SECRET_KEY="%s"\n' % (secretkey)
sys.stdout.write(line)
The output is:
AWS_ACCESS_KEY="xxxxxxx"
AWS_SECRET_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxx"
Now, output is correct, butI have to overwrite the file, how can I do?
Use inplace=True
Ex:
import fileinput
with fileinput.input(files='./envFile.sh', inplace=True) as envfile:
for line in envfile:
if line.strip().startswith('export AWS_ACCESS_KEY='):
print(line.replace(line.strip(), 'AWS_ACCESS_KEY="%s"' % (accesskey)))
elif line.strip().startswith('export AWS_SECRET_KEY='):
print(line.replace(line.strip(), 'AWS_SECRET_KEY="%s"' % (secretkey)))
else:
print(line)
You can store all of your result into one list and iterate over to that list and write into the file using "with statement"
as shown below
temp='AWS_ACCESS_KEY="{}"\n'.format(accesskey)
a.append(temp)
temp='AWS_SECRET_KEY="{}"\n'.format(secretkey)
a.append(temp)
with open(file_name,'w') as stream:
for i in a:
stream.write(i)

How to replace a string in a file?

I have 2 numbers in two similar files. There is a new.txt and original.txt. They both have the same string in them except for a number. The new.txt has a string that says boothNumber="3". The original.txt has a string that says boothNumber="1".
I want to be able to read the new.txt, pick the number 3 out of it and replace the number 1 in original.txt.
Any suggestions? Here is what I am trying.
import re # used to replace string
import sys # some of these are use for other code in my program
def readconfig():
with open("new.text") as f:
with open("original.txt", "w") as f1:
for line in f:
match = re.search(r'(?<=boothNumber=")\d+', line)
for line in f1:
pattern = re.search(r'(?<=boothNumber=")\d+', line)
if re.search(pattern, line):
sys.stdout.write(re.sub(pattern, match, line))
When I run this, my original.txt gets completely cleared of any text.
I did a traceback and I get this:
in readconfig
for line in f1:
io.UnsupportedOperationo: not readable
UPDATE
I tried:
def readconfig(original_txt_path="original.txt",
new_txt_path="new.txt"):
with open(new_txt_path) as f:
for line in f:
if not ('boothNumber=') in line:
continue
booth_number = int(line.replace('boothNumber=', ''))
# do we need check if there are more than one 'boothNumber=...' line?
break
with open(original_txt_path) as f1:
modified_lines = [line.startswith('boothNumber=') if not line
else 'boothNumber={}'.format(booth_number)
for line in f1]
with open(original_txt_path, mode='w') as f1:
f1.writelines(modified_lines)
And I get error:
booth_number = int(line.replace('boothNumber=', ''))
ValueError: invalid literal for int() with base 10: '
(workstationID="1" "1" window=1= area="" extra parts of the line here)\n
the "1" after workstationID="1" is where the boothNumber=" " would normally go. When I open up original.txt, I see that it actually did not change anything.
UPDATE 3
Here is my code in full. Note, the file names are changed but I'm still trying to do the same thing. This is another idea or revision I had that is still not working:
import os
import shutil
import fileinput
import re # used to replace string
import sys # prevents extra lines being inputed in config
# example: sys.stdout.write
def convertconfig(pattern):
source = "template.config"
with fileinput.FileInput(source, inplace=True, backup='.bak') as file:
for line in file:
match = r'(?<=boothNumber=")\d+'
sys.stdout.write(re.sub(match, pattern, line))
def readconfig():
source = "bingo.config"
pattern = r'(?<=boothNumber=")\d+' # !!!!!!!!!! This probably needs fixed
with fileinput.FileInput(source, inplace=True, backup='.bak') as file:
for line in file:
if re.search(pattern, line):
fileinput.close()
convertconfig(pattern)
def copyfrom(servername):
source = r'//' + servername + '/c$/remotedirectory'
dest = r"C:/myprogram"
file = "bingo.config"
try:
shutil.copyfile(os.path.join(source, file), os.path.join(dest, file))
except:
print ("Error")
readconfig()
# begin here
os.system('cls' if os.name == 'nt' else 'clear')
array = []
with open("serverlist.txt", "r") as f:
for servername in f:
copyfrom(servername.strip())
bingo.config is my new file
template.config is my original
It's replacing the number in template.config with the literal string "r'(?<=boothNumber=")\d+'"
So template.config ends up looking like
boothNumber="r'(?<=boothNumber=")\d+'"
instead of
boothNumber="2"
To find boothNumber value we can use next regular expression (checked with regex101)
(?<=\sboothNumber=\")(\d+)(?=\")
Something like this should work
import re
import sys # some of these are use for other code in my program
BOOTH_NUMBER_RE = re.compile('(?<=\sboothNumber=\")(\d+)(?=\")')
search_booth_number = BOOTH_NUMBER_RE.search
replace_booth_number = BOOTH_NUMBER_RE.sub
def readconfig(original_txt_path="original.txt",
new_txt_path="new.txt"):
with open(new_txt_path) as f:
for line in f:
search_res = search_booth_number(line)
if search_res is None:
continue
booth_number = int(search_res.group(0))
# do we need check if there are more than one 'boothNumber=...' line?
break
else:
# no 'boothNumber=...' line was found, so next lines will fail,
# maybe we should raise exception like
# raise Exception('no line starting with "boothNumber" was found')
# or assign some default value
# booth_number = -1
# or just return?
return
with open(original_txt_path) as f:
modified_lines = []
for line in f:
search_res = search_booth_number(line)
if search_res is not None:
line = replace_booth_number(str(booth_number), line)
modified_lines.append(line)
with open(original_txt_path, mode='w') as f:
f.writelines(modified_lines)
Test
# Preparation
with open('new.txt', mode='w') as f:
f.write('some\n')
f.write('<jack Fill workstationID="1" boothNumber="56565" window="17" Code="" area="" section="" location="" touchScreen="False" secureWorkstation="false">')
with open('original.txt', mode='w') as f:
f.write('other\n')
f.write('<jack Fill workstationID="1" boothNumber="23" window="17" Code="" area="" section="" location="" touchScreen="False" secureWorkstation="false">')
# Invocation
readconfig()
# Checking output
with open('original.txt') as f:
for line in f:
# stripping newline character
print(line.rstrip('\n'))
gives
other
<jack Fill workstationID="1" boothNumber="56565" window="17" Code="" area="" section="" location="" touchScreen="False" secureWorkstation="false">

In python, how would I delete a line in a file if query matches a result

I have a text file with a list of values that I need to query against in MySQL. If the result from the query returns 1 or more rows, i need to delete the line from the file. I will run the query until the file is empty.
# cat file.txt
bob
susan
jeff
mary
# cat script.py
f = open('file.txt')
for line in f:
# mysql query to get 'query_result'
if query_result == 1:
# do some work
# proceed to delete the value from the file
I recommend the with open syntax (it will close your file for you):
fileLines = []
with open('field.txt') as f:
for line in f:
# mysql query to get 'query_result'
if query_result != 1:
fileLines.append(line) # These will be the lines you actually want
with open('field.txt', 'w') as f:
for line in fileLines:
f.write(line)
This will essentially rewrite the whole file. So be careful with it, if you query frequently, you will probably want to load the file lines and make temp changes, periodically updating the file. You might also want to load the temp data into a temp file for persistence.
Manipulating the file isn't necessary. I think it's ok to just do this:
f = open('file.txt')
lines = f.readlines()
deleted = set()
for line in lines:
line = line.strip()
if line in deleted:
continue
# do query
if query_result == 1:
deleted.add(line)

Remove duplicates after altering items

I have a script to clean urls to get base domains from example.com/example1 and example.com/example2 down to example.com My issue is when it goes to through the file of urls it will have duplicate base domains. I want to remove the duplicates while printing the urls to a file. below is the code I currently have.
enter from Tkinter import *
import tkFileDialog
import re
def main():
fileOpen = Tk()
fileOpen.withdraw() #hiding tkinter window
file_path = tkFileDialog.askopenfilename(
title="Open file", filetypes=[("txt file",".txt")])
if file_path != "":
print "you chose file with path:", file_path
else:
print "you didn't open anything!"
fin = open(file_path)
fout = open("URL Cleaned.txt", "wt")
for line in fin.readlines():
editor = (line.replace('[.]', '.')
.replace('[dot]', '.')
.replace('hxxp://www.', '')
.replace('hxxps://www.', '')
.replace('hxxps://', '')
.replace('hxxp://', '')
.replace('www.', '')
.replace('http://www.', '')
.replace('https://www.', '')
.replace('https://', '')
.replace('http://', ''))
editor = re.sub(r'/.*', '', editor)
if __name__ == '__main__':
main()
Any help is appreciated. I have scoured the posts and tried all of the suggestions for my issue and have not found one that works.
You can use regular expresion to find the base domains.
If you have one url per line in your file:
import re
def main():
file = open("url.txt",'r')
domains = set()
# will works for any web like https://www.domain.com/something/somethingmore... , also without www, without https or just for www.domain.org
matcher= re.compile("(h..ps?://)?(?P<domain>(www\.)?[^/]*)/?.*")
for line in file:
# make here any replace you need with obfuscated urls like: line = line.replace('[.]','.')
if line[-1] == '\n': # remove "\n" from end of line if present
line = line[0:-1]
match = matcher.search(line)
if match != None: # If a url has been found
domains.add(match.group('domain'))
print domains
file.close()
main()
For example, with this file, it will print:
set(['platinum-shakers.net', 'wmi.ns01.us', 'adservice.no-ip.org', 'samczeruno.pl', 'java.ns1.name', 'microsoft.dhcp.biz', 'ids.us01.us', 'devsite.quostar.com', 'orlandmart.com'])
perhaps you could use a regular expression:
import re
p = re.compile(r".*\.com/(.*)") # to get for instance 'example1' or 'example2' etc.
with open(file_path) as fin, open("URL Cleaned.txt", "wt") as fout:
lines = fin.readlines():
bases = set(re.search(p, line).groups()[0] for line in lines if len(line) > 1)
for b in bases:
fout.write(b)
Using with open(..) auto closes the files after the executing the block of code
Output:
Using a text file with:
www.example.com/example1
www.example.com/example2
# blank lines are accounted for
www.example.com/example3
www.example.com/example4
www.example.com/example4 # as are duplicates
as the lines, I got the output,
example1
example2
example3
example4

How to read and divide individual lines of a file in python?

Thanks to stackoverflow, I am able to read and copy a file. However, I need to read a picture file one line at a time, and the buffer array can't exceed 3,000 integers. How would I separate the lines, read them, and then copy them? Is that the best way to execute this?
Here is my code, courtesy of #Chayim:
import os
import sys
import shutil
import readline
source = raw_input("Enter source file path: ")
dest = raw_input("Enter destination path: ")
file1 = open(source,'r')
if not os.path.isfile(source):
print "Source file %s does not exist." % source
sys.exit(3)
file_line = infile.readline()
try:
shutil.copy(source, dest)
infile = open(source,'r')
outfile = open(dest,'r')
file_contents = infile.read()
file_contents2 = outfile.read()
print(file_contents)
print(file_contents2)
infile.close()
outfile.close()
except IOError, e:
print "Could not copy file %s to destination %s" % (source, dest)
print e
sys.exit(3)
I added
file_line = infile.readline()
but I'm concerned that infile.readline() will return a string, instead of integers. Also, how do I limit the number of integers it processes?
I think you want to do something like this:
infile = open(source,'r')
file_contents_lines = infile.readlines()
for line in file_contents_lines:
print line
This will get you all the lines in the file and put them into a list containing each line as an element in the list.
Take a look at the documentation here.

Categories

Resources