I have a log file where i'm fetching only the desired output and into two different variables and when i run the code it prints currently but i need both the variable data written into another file called file1.
I have the raw code sample which i tried working with print but not getting the idea about writing it into a file.
with open("testfile","r") as fh:
for line in fh:
if "ping" in line:
if HOST != "NA" and Flag:
mydata1 = hostname
elif HOST != "NA" and Flag and HOST not in mydata1:
mydata2 = logname
mydata3 = open('file1', 'w')
mydata3.write(mydata1,mydata2)
mydata3.close()
#print(mydata1,mydata2)
Try using str.format:
Ex:
with open("testfile","r") as fh:
for line in fh:
if "ping" in line:
if HOST != "NA" and Flag:
mydata1 = hostname
elif HOST != "NA" and Flag == True and HOST not in mydata1:
mydata2 = logname
mydata3 = open('file1', 'w')
mydata3.write("{0} {1}".format(mydata1,mydata2))
mydata3.close()
Related
I have a text file which contains this information:
network={
ssid="WIFI_SSID"
scan_ssid=1
psk="WIFI_PASSWORD"
key_mgmt=WPA-PSK
}
I want to modify this text file and change the ssid and psk values. so I want something like this:
network={
ssid="KB150"
scan_ssid=1
psk="testpass"
key_mgmt=WPA-PSK
}
I wrote this code, but it only can add a new line at end of the file only for ssid (something like ssid= KB150):
if __name__ == '__main__':
ssid = "KB150"
password = "testpass"
with open("example.txt", 'r+') as outfile:
for line in outfile:
if line.startswith("ssid"):
sd = line.split("= ")
outfile.write(line.replace(sd[1], ssid))
if line.startswith("password"):
pw = line.split("= ")
line.replace(pw[1], password)
outfile.write(line.replace(pw[1], ssid))
outfile.close()
The values of ssid and psk change whenever a user enter an input in my program, so I need to find the line that starts with those keywords and change their values.
Since the file is small, you can read it fully, do the replacement and write back. You don't have to close it explicitly as with handles it.
if __name__ == '__main__':
ssid = "KB150"
password = "testpass"
# open for reading
with open("example.txt", 'r') as infile:
content = infile.read()
# reopen it for writing
with open("example.txt", 'w') as outfile:
content = content.replace("WIFI_SSID", ssid).replace("WIFI_PASSWORD", password)
outfile.write(content)
Modifying file while reading is tricky. Discussed here
Edit
There are multiple ways to handle it. You can keep a template file with the content.
network={
ssid="WIFI_SSID"
scan_ssid=1
psk="WIFI_PASSWORD"
key_mgmt=WPA-PSK
}
The script can read the content of template file, replace ssid and password and write to target file.
Another way is to use regex replacement like
import re
if __name__ == '__main__':
ssid = "KB150"
password = "testpass"
with open("example.txt", 'r') as infile:
content = infile.read()
# reopen it for writing
with open("example.txt", 'w') as outfile:
content = re.sub('ssid="[^"]*"', f'ssid="{ssid}"', content)
content = re.sub('psk="[^"]*"', f'psk="{password}"', content)
outfile.write(content)
I would guess your line.startswith("ssid") is not returning True, because in your example.txt are whitespaces before "ssid". So you maybe want to think about spliting the line with the right amound of whitespaces or search for ssid in every line.
Thanks to Shanavas M (having his useful tip in my mind), My friend helped me and I got finally what I want:)
fileName = 'example.txt'
result = ""
ssid = "KB150"
password = "testpass"
with open(fileName, 'r') as filehandle:
for line in filehandle:
temp = line.split('=')[0]
if temp == "ssid ":
result += 'ssid = "{}"\n'.format(ssid)
elif temp == 'password ':
result += 'password = "{}"\n'.format(password)
else:
result += line
with open(fileName, 'w') as filehandle:
filehandle.write(result)
Background Information
I have a program that I'm using for pinging a service and printing the results back to a window. I'm currently trying to add to this program, by adding a kind of 'settings' file that users can edit to change the a) host that is pinged and b) timeout
What I've tried so far
file = open("file.txt", "r")
print (file.read())
settings = file.read()
# looking for the value of 'host'
pattern = 'host = "(.*)'
variable = re.findall(pattern, settings)[0]
print(test)
As for what is contained within the file.txt file:
host = "youtube.com"
pingTimeout = "1"
However, my attempts have been unsuccessful as this comes up with the following
error:
IndexError: list index out of range
And so, my question is:
Can anyone point me in the right direction to do this? To recap, I am asking how I can take an input from file (in this case host = "youtube.com" and save that as a variable 'host' within the python file).
First, as Patrick Haugh pointed out, you can't call read() twice on the same file object. Second, using regex to parse a simple key = value format is a bit overkill.
host, pingTimeout = None,None # Maybe intialize these to a default value
with open("settings.txt", "r") as f:
for line in f:
key,value = line.strip().split(" = ")
if key == 'host':
host = value
if key == 'pingTimeout':
pingTimeout = int(value)
print host, pingTimeout
Note that the expected input format would have no quotes for the example code above.
host = youtube.com
pingTimeout = 1
I tried this, it may help :
import re
filename = "<your text file with hostname>"
with open(filename) as f:
lines = f.read().splitlines()
for str in lines:
if re.search('host', str):
host, val = str.split('=')
val = val.replace("\"", "")
break
host = val
print host
f.close()
I am trying to write system info to a spreadsheet. but when I try to use my variables they come out black
import csv
import os
import linecache
os.system('getmac -v > mac.txt')
os.system("wmic bios get serialnumber > serial.txt")
os.system("wmic computersystem get model > model.txt")
os.system("hostname > hostname.txt")
os.system("ipconfig > ip.txt")
open('ip1.txt','w').writelines([line for line in open('ip.txt')if 'IPv4' in line])
open('mac1.txt','w').writelines([line for line in open('mac.txt')if 'Wi-Fi' in line])
open('mac2.txt','w').writelines([line for line in open('mac.txt')if 'Ethernet' in line])
serial = linecache.getline('serial.txt', 3)
model = linecache.getline('model.txt', 3)
mac = open("mac.txt","r")
IP = open("ip1.txt","r")
mac1 = open("mac1.txt","r")
mac2 = open("mac2.txt","r")
hostname = open("hostname.txt","r")
Rmac = mac.read()
Rip = IP.read()
Rmac1 = mac1.read()
Rmac2 = mac2.read()
Rhostname = hostname.read()
myData = [[model]]
myFile = open('example2.csv', 'w')
with myFile:
writer = csv.writer(myFile)
writer.writerows(myData)
this just will not write the information to the spreadsheet? what am I doing wrong? I am very new to programming btw
You don't need intermediary files, why not call your commands and write their info to your CSV immediately without all that back and forward dancing?
import csv
import subprocess
# get the model
model = subprocess.check_output(["WMIC", "computersystem", "get", "model"],
universal_newlines=True).strip().rsplit("\n", 1)[1]
# get the serial
serial = subprocess.check_output(["WMIC", "bios", "get", "serialnumber"],
universal_newlines=True).strip().rsplit("\n", 1)[1]
# get the host name
hostname = subprocess.check_output(["hostname"], universal_newlines=True).strip()
# get WMI output for all addresses
ips = subprocess.check_output(["WMIC", "NICCONFIG", "where", "IPEnabled=true",
"get", "IPAddress"],
universal_newlines=True).strip().split("\n\n")[1:]
# post-process to get the addresses only
ips = [ip.split(",")[0].strip('"{} ') for ip in ips]
# etc.
with open("example2.csv", "wb") as f: # open your CSV for writing
writer = csv.writer(f) # create a writer
# you didn't write a header but let's add it in
writer.writerow(["model", "serial", "hostname", "ips"]) # etc., you get the picture...
writer.writerow([model, serial, hostname, ",".join(ips)]) # add other columns, too
And you'll get a nice example2.csv containing:
model,serial,hostname,ips
Your Model,Your Serial,Your-Hostname,List.Of.IP.Addresses
Do the same for the other fields and you're done.
I have one file named mcelog.conf and I am reading this file in my code. Contents of the file are
no-syslog = yes # (or no to disable)
logfile = /tmp/logfile
Program will read the mcelog.conf file and will check for the no-syslog tag, if no-syslog = yes then program has to check for the tag logfile and will read the logfile tag. Can anyone let me know how I can get the value /tmp/logfile
with open('/etc/mcelog/mcelog.conf', 'r+') as fp:
for line in fp:
if re.search("no-syslog =", line) and re.search("= no", line):
memoryErrors = readLogFile("/var/log/messages")
mcelogPathFound = true
break
elif re.search("no-syslog =", line) and re.search("= yes", line):
continue
elif re.search("logfile =", line):
memoryErrors = readLogFile(line) # Here I want to pass the value "/tmp/logfile" but currently "logfile = /tmp/logfile" is getting passed
mcelogPathFound = true
break
fp.close()
You can just split the line to get the value you want:
line.split(' = ')[1]
However, you might want to look at the documentation for configparser module.
Change the code to:
with open('/etc/mcelog/mcelog.conf', 'r+') as fp:
for line in fp:
if re.search("no-syslog =", line) and re.search("= no", line):
memoryErrors = readLogFile("/var/log/messages")
mcelogPathFound = true
break
elif re.search("no-syslog =", line) and re.search("= yes", line):
continue
elif re.search("logfile =", line):
emoryErrors = readLogFile(line.split("=")[1].strip()) # Here I want to pass the value "/tmp/logfile" but currently "logfile = /tmp/logfile" is getting passed
mcelogPathFound = true
break
fp.close()
This is because you want to read only a part of the line rather the whole thing so I have just split it up by the "=" sign and then stripped it to remove any blanks
I liked the suggestion of the configparser module, so here is an example of that (Python 3)
For the given input, it will output reading /var/log/messages
import configparser, itertools
config = configparser.ConfigParser()
filename = "/tmp/mcelog.conf"
def readLogFile(filename):
if filename:
print("reading", filename)
else:
raise ValueError("unable to read file")
section = 'global'
with open(filename) as fp:
config.read_file(itertools.chain(['[{}]'.format(section)], fp), source = filename)
no_syslog = config[section]['no-syslog']
if no_syslog == 'yes':
logfile = "/var/log/messages"
elif no_syslog == 'no':
logfile = config[section]['logfile']
if logfile:
mcelogPathFound = True
memoryErrors = readLogFile(logfile)
I am using this code to search for emails in a particular file and write them into a another file. I have used 'in' operator to make sure that the email are not duplicated.
But this code does not get executed after the for line in f: line.
Can any one point out the mistake i have made here?
tempPath = input("Please Enter the Path of the File\n")
temp_file = open(tempPath, "r")
fileContent = temp_file.read()
temp_file.close()
pattern_normal = re.compile("[-a-zA-Z0-9._]+#[-a-zA-Z0-9_]+.[a-zA-Z0-9_.]+")
pattern_normal_list = pattern_normal.findall(str(fileContent))
with open('emails_file.txt', 'a+') as f:
for item in pattern_normal_list:
for line in f:
if line in item:
print("duplicate")
else:
print("%s" %item)
f.write("%s" %item)
f.write('\n')
New solution:
tempPath = input("Please Enter the Path of the File\n")
temp_file = open(tempPath, "r")
fileContent = temp_file.read()
temp_file.close()
pattern_normal = re.compile("[-a-zA-Z0-9._]+#[-a-zA-Z0-9_]+.[a-zA-Z0-9_.]+")
addresses = list(set(pattern_normal.findall(str(fileContent))))
with open('new_emails.txt', 'a+') as f:
f.write('\n'.join(addresses))
I think your logic was wrong, this works:
addresses = ['test#wham.com', 'heffa#wham.com']
with open('emails_file.txt', 'a+') as f:
fdata = f.read()
for mail in addresses:
if not mail in fdata:
f.write(mail + '\n')
Without reading to much into your code,
it looks like youre looping line by line, checking if the address you've also looping through exists in the line, if it doesn't you append your e-mail to it? But in 99% of a 100 lines the address will not be in the line, hence you'll get an unwanted addition.
Output of my code snippet:
[Torxed#faparch ~]$ cat emails_file.txt
test#wham.com
Torxed#whoever.com
[Torxed#faparch ~]$ python test.py
[Torxed#faparch ~]$ cat emails_file.txt
test#wham.com
Torxed#whoever.com
heffa#wham.com
[Torxed#faparch ~]$
for line in f:
Shouldn't you first call f.readlines()?
lines = f.readlines()
for line in lines:
Check this.