find and print - regular expression - python

This program is to login to my switch and copies output to a file; and the second part is for finding a keyword and print the entire line.
When I run the code the first part works fine but second part of the code does not print the line containing the key word i am looking for..
However, when i run the second part of the code separately i am able to print the line containing the key_word.
What is wrong here? Pease help me out?
import paramiko
import sys
import re
host = "15.112.34.36"
port = 22
username = "admin"
password = "ssmssm99"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
commands = ["switchshow"]
for command in commands:
print(command)
sys.stdout = open('zones_list.txt', 'w')
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
lines = "".join(lines)
print(lines)
ssh.close()
#SECOND PART
#open the zone_list file and search for a keyword
#search for wwn and print the entire line --> doesnt print why?
wwn = "10:00:00:90:fa:73:df:c9"
with open('zones_list.txt', 'r') as f:
lines = f.readlines()
for line in lines:
if re.search(r'10:00:00:90:fa:73:df:c9', line):
print (line)
break

You're redicting stdout to a file in line 17:
sys.stdout = open('zones_list.txt', 'w')
All print statements afterwards don't write to the console, but to the file.
Secondly you open the same file twice, once for writing and once for reading, but in the second case f.readlines() returns an empty list.
Example to show why it's problematic to open the file twice.
import sys
# 1. Opening the file without closing it => will be closed at the end of the program
# 2. stdout now writes into the file
sys.stdout = open('text3', 'w')
# Will be writen into the file when the program finishes
print ('line1')
print ('line2')
# We open the file a second time
with open('text3', 'r') as f:
# lines will always be an empty list, no matter if there was something in the file before
lines = f.readlines()
# Writing to stderr so we see the output in the console (stdout still points at the file)
sys.stderr.write('length: {}'.format(len(lines)))
for line in lines:
# We should never be here
sys.stderr.write (line)
# write some more stuff the the file
for i in range(1, 6):
print ('i + {}'.format(i))
print('line3')

The first part of the script redirected stdout to the file. So print(line) in the second part is also writing to the file instead of displaying the matching line. Also, you never closed the file in the first part, so buffered output won't be written to the file.
Don't use sys.stdout in the first part, use an ordinary variable.
Another problem is that you're overwriting the file for each command in commands. You should open the file once before the loop, not each time through the loop.
wwn isn't a regular expression, there's no need to use re.search(). Just use if wwn in line:. And you don't need to use f.readlines(), just loop through the file itself.
import paramiko
import sys
host = "15.112.34.36"
port = 22
username = "admin"
password = "ssmssm99"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
commands = ["switchshow"]
with open('zones_list.txt', 'w') as f:
for command in commands:
print(command)
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
lines = "".join(lines)
print(lines, file=f)
ssh.close()
#SECOND PART
#open the zone_list file and search for a keyword
#search for wwn and print the entire line --> doesnt print why?
wwn = "10:00:00:90:fa:73:df:c9"
with open('zones_list.txt', 'r') as f:
for line in f:
if wwn in line:
print (line)
break

got the code straight. And couple of questions to bug you and Maddi.
This code asks the user to enter the "wwn" to search for in the host and print the line which contains the "wwn" number.
Question1: I would run this code multiple times whenever I would like to search for "wwn"...
And here I would like to have a clear "zones_list.txt" file each time I start. So I opened the file in 'w' mode -- SO this clears each time right? Any other suggestion?
Question2: IS there any other way to store the output and search it for a string and print the output? I guess storing the data in a file and searching through it is the best?
Question3: I would like to add a GUI where user is asked to enter the "wwn" and print the output. Any suggestion?
Thanks again :)
import paramiko
import sys
import re
#host details to fetch data - nodefind
host = "15.112.34.36"
port = 22
username = "admin"
password = "ssmssm99"
#shell into the client host
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
#asking user to enter the wwn to search in the host
wwn = input('Enter the wwn to be searched >')
#for example command is: nodefind 20:34:00:02:ac:07:e9:d5
commands = ["nodefind " + wwn, "switchshow"]
f =open('zones_list.txt', 'w')
for command in commands:
print(command)
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
lines = "".join(lines)
print(lines, file=open('zones_list.txt', 'a'))
ssh.close()
#print a particular line in console to the user
f =open('zones_list.txt', 'r')
for line in f:
if wwn in line:
print(line)
break

Related

how to construct loop and write netmiko commands to files using python

As per the below script, it adds both commands to output.txt.
Instead how to add "show system" command to output1.txt and "show run" command to output2.txt.
Python Script:
Import program dependencies
from netmiko import ConnectHandler
import getpass
Read from a list of hostnames to connect to
hosts = open('hosts.txt','r')
hosts = hosts.read()
hosts = hosts.strip().splitlines()
Get UserName and password from input
userName = input('Username: ')
passWord = getpass.getpass()
Loop to process hosts in hosts.txt file
for host in hosts:
# Define device type and connection attributes
Brocade_ICX = {
'device_type': 'brocade_fastiron',
'ip': host,
'username': userName,
'password': passWord),
}
# Netmiko SSH Connection Handler
net_connect = ConnectHandler(**Brocade_ICX)
#open file to write command output
file = open('output.txt', 'w')
# Execute commands
output = net_connect.send_command('show system')
output = net_connect.send_command('show run')
# Print output to console screen
print('-------------- Output from ' + host + '------------------')
print(output)
print()
print()
# Write output to file above
file.write(output)
file.close()
you are doing the looping wrong..
think about the last iteration of j variable in the loop
it points to c then inner loop goes through each file and and writes c to them
to fix it you need only one loop
for i in range(len(command)):
file = open(command[i] +'_output.txt', 'w')
file.write(output[i])
file.close()
Follow just four simple steps to get the solution.
Opening a text file.
file = open('text file','w')
Adding a test line in the file.
file.write('We will be seeing aninterated printing of numbers between 0 to 10\n')
Writing a for loop over the file.
for i in range(0,11):
file.write(str(i))
file.write('\n')
Closing the text file.
file.close()

Check if command line argument is already used

I'm trying to check reverse lookup of IP address (argument). and then write the result to txt file.
How I can check if the IP address (argument) is already registered in the file? If so, I need to get out of the script.
My script:
import sys, os, re, shlex, urllib, subprocess
cmd = 'dig -x %s #192.1.1.1' % sys.argv[1]
proc = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
out, err = proc.communicate()
# Convert to list of str lines
out = out.decode().split('\n')
# Only write the line containing "PTR"
with open("/tmp/test.txt", "w") as f:
for line in out:
if "PTR" in line:
f.write(line)
If the file is not too large you could do:
with open('file.txt','r') as f:
content = f.read()
if ip in content:
sys.exit(0)
Now if the file is big and you want to avoid possible memory problems you could use mmap like so:
import mmap
with open("file.txt", "r+b") as f:
# memory-map the file, size 0 means whole file
mm = mmap.mmap(f.fileno(), 0)
if mm.find(ip) != -1:
sys.exit(0)
The mmap.find(string[, start[, end]]) is well documented here.
Something like:
otherIps = [line.strip() for line in open("<path to ipFile>", 'r')]
theIp = "192.168.1.1"
if theIp in otherIps:
sys.exit(0)
otherIps contains a list of the ip addresses on ipFile, then you need to check if theIp is already on otherIps, if so, exit the script.

Python How to generate file name

I was wondering if the community can help me out I'm a newbie to programming. I trying to ssh to a list of devices contain on "list.txt" once it logs into the router I send the same command to each one and write the output to a file. However, on the code below it overrides the output of each device. I need to create a unique file for each output with the name of the IP address that is contains on the "list.txt" file. If anybody can help me out I would really appreciated.
import paramiko
import time
import os
def disable_paging(remote_conn):
'''Disable paging on a Cisco router'''
remote_conn.send("terminal length 0\n")
time.sleep(1)
# Clear the buffer on the screen
output = remote_conn.recv(1000)
return output
#Create variables
f = open('list.txt')
filepath = ('test/tas.txt')
username = 'test'
password = 'test'
#Create a for loop
for i in f:
remote_conn_pre = paramiko.SSHClient()
remote_conn_pre.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
remote_conn_pre.connect(i, username=username, password=password)
remote_conn = remote_conn_pre.invoke_shell()
output = remote_conn.recv(1000)
disable_paging(remote_conn)
# Now let's try to send the router a command
remote_conn.send("\n")
remote_conn.send("show int des\n")
# Wait for the command to complete
time.sleep(2)
output = remote_conn.recv(88880000)
# print output
if not os.path.exists(os.path.dirname(filepath)):
os.makedirs(os.path.dirname(filepath))
with open(filepath, "w") as f:
f.write(output)
f.close()
You could just have your 'filepath' variable defined in the for loop, and use the 'i' string to create it :
for i in f:
filename = 'tas_%s.txt' % str(i)
filepath = os.path.join('test', filename)
# anything else remains unchanged
Hope it works (difficult without knowing the content of 'list.txt').

Python 2.7 Loop through multiple subprocess.check_output calls

I am having an issue with printing output from subprocess.check_output calls.
I have a list of IP addresses in ip.txt that I read from and save to list ips.
I then iterate over that list and call wmic command to get some details from that machine, however only the last command called prints output. By looking at CLI output, I can see that print 'Complete\n' is called for each, but check_output is not returning anything to output variable.
Any ideas? Thanks
Python Code:
from subprocess import check_output
f_in = open('ip.txt', 'r')
ips = []
for ip in f_in:
ips.append(ip)
f_in.close()
f_out = open('pcs.txt','w')
for ip in ips:
cmd = 'wmic /node:%s computersystem get name,username' % (ip)
f_out.write('Trying %s\n'%ip)
print 'Trying: %s' % (ip)
try:
output = check_output(cmd,shell=True)
f_out.write(output)
print 'Output\n--------\n%s' % output
print 'Complete\n'
except:
f_out.write('Could not complete wmic call... \n\n')
print 'Failed\n'
f_out.close()
File Output:
Trying 172.16.5.133
Trying 172.16.5.135
Trying 172.16.5.98
Trying 172.16.5.131
Name UserName
DOMAINWS48 DOMAIN\staff
CLI Output
Trying: 172.16.5.133
Output
Complete
Trying: 172.16.5.135
Output
Complete
Trying: 172.16.5.98
Output
Complete
Trying: 172.16.5.131
Output
Name UserName
DOMAINWS48 DOMAIN\staff
Complete
In these lines you read a file line by line:
f_in = open('ip.txt', 'r')
ips = []
for ip in f_in:
ips.append(ip)
Unfortunately each line has an end of line character still terminating each line. You then pass the newline in as part of the IP address. You might want to consider stripping the newlines \n from the end of each line you read:
f_in = open('ip.txt', 'r')
ips = []
for ip in f_in:
ips.append(ip.strip('\n'))
strip('\n') will strip all the newlines from the beginning and end of the string. Information on this string method can be found in the Python documentation:
str.strip([chars])
Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped:
You can also read all the lines from the file with something like:
ips = [line.strip('\n') for line in f_in.readlines()]
My guess is that your ip.txt file has an IP address on each line and the last line of the file is not terminated with a newline \n and in that case your code worked.

Read file and copy to standard output.

I'm trying to write a python program that will read input and copy it to standard output (with no alterations). I've been told that it needs to operate as a Python version of the Unix cat function. If a file cannot be opened, an error message needs to be printed, and then the program needs to continue processing any additional files. I am a complete beginner, and have tried my best to scrape something together with my limited knowledge. Here is what I have so far:
from sys import argv, stdout, stdin, stderr
if len(argv) == 1:
try:
stdout.write(raw_input(' ') + '\n')
except:
stderr.write ('sorry' + '\n')
quit()
else:
for filename in argv[1:]:
try:
filehandle + open(filename)
except IOError:
stderr.write('Sorry, could not open', filename + '\n')
continue
f = filehandle.read()
stdout.write(f)
I am not quite sure where to go from here.. does anyone have any advice/am I on the right track even a little bit? Please and thank you!
This function will copy the specified file to the console line by line (in case you later on decide to give it the ability to use the -n command line option of cat)
def catfile(fn):
with open(fn) as f:
for line in f:
print line,
It can be called with the filename once you have established the file exists.

Categories

Resources