0

Below is the input data:

crypto map outside_map0 1 set peer 1.1.1.1
crypto map outside_map0 1 ikev1 transform-set ESP-AES-256-SHA
crypto map outside_map0 2 set peer 2.2.2.2
crypto map outside_map0 2 ikev1 transform-set ESP-AES-256-SHA
crypto map outside_map0 3 set peer 3.3.3.3
crypto map outside_map0 3 ikev1 transform-set ESP-AES-256-SHA
crypto map outside_map0 4 set peer 4.4.4.4
crypto map outside_map0 4 ikev1 transform-set ESP-3DES-SHA

I want my output data to look like this:

1, 1.1.1.1, ESP-AES-256-SHA
2, 2.2.2.2, ESP-AES-256-SHA
3, 3.3.3.3, ESP-AES-256-SHA
4, 4.4.4.4, ESP-3DES-SHA

Current script i have is this:

fo = open('vpn.txt', 'r')
for line in fo.readlines():
    list = line.split(" ")
    if "peer" in list:
        print list[3] + "," + list[6] + "," + next(list[6])

I'm having a hard time understanding the usage of the next function.

Jonas
  • 121,568
  • 97
  • 310
  • 388
JoeScripter
  • 43
  • 1
  • 7
  • What are *you* attempting to accomplish with that call to `next`? How do you imagine it should work? Explaining that would go a long way to helping you. – Mad Physicist Nov 11 '19 at 18:39
  • After finding "peer" in line 1, I need a way to access line 2. Then break the loop and move on to line 3 (which will have "peer" in the line, which will then lead me to line 4 to get the ciphers being used) and so on... – JoeScripter Nov 11 '19 at 18:42
  • I imagine there is a "cleaner" way to do this also. I'm not at all married to what I came up with above – JoeScripter Nov 11 '19 at 18:43
  • Possible duplicate of [How do I read two lines from a file at a time using python](https://stackoverflow.com/questions/1657299/how-do-i-read-two-lines-from-a-file-at-a-time-using-python) – Boris Verkhovskiy Nov 11 '19 at 18:49
  • @JoeScripter why don't you used `.split()` for the second line too? Also, switch to Python 3, the Python version you're writting your script with will be end of lifed in January. – Boris Verkhovskiy Nov 11 '19 at 18:59
  • I don't understand your comment, did you solve your problem or is there something else? – Boris Verkhovskiy Nov 11 '19 at 19:01
  • The solution is to process two lines at a time in your loop. – Code-Apprentice Nov 11 '19 at 19:12

4 Answers4

1

It is possible to do what you want using the next function, but it won't be the simplest, most-understandable way of solving this problem. I don't recommend trying to use next here.

You have a for loop over the lines in the file, but really you want to read two lines at a time, because each "item" of data depends on two lines in the file. I suggest solving this problem in three parts:

  1. First, design a way of representing the data as an object (e.g. a tuple, or a namedtuple).
  2. Write a while loop to read two lines of the file at a time, extracting the data from those two lines to create an object, and collect those objects in a list.
  3. Iterate over the list of objects, printing out the data you want from each object.

The solution to part 2 could look like this:

results = []

with open('vpn.txt', 'r') as f:
    line1, line2 = f.readline(), f.readline()
    while line1 and line2:
        _, _, _, id_number, _, _, ip_address = line1.split()
        algorithm = line2.split()[-1]
        obj = (id_number, ip_address, algorithm)
        results.append(obj)

        line1, line2 = f.readline(), f.readline()
kaya3
  • 47,440
  • 4
  • 68
  • 97
  • This will ignore the last line if your file contains an odd number of lines. – Boris Verkhovskiy Nov 11 '19 at 18:54
  • The file format described in the question cannot legally have an odd number of lines containing meaningful data; I have simply declined to write code checking that the file *is* in the required format. – kaya3 Nov 11 '19 at 18:55
1
with open("vpn.txt") as f:
    for index, (line1, line2) in enumerate(zip(f, f), start=1):
        peer_ip = line1.split()[-1]
        cipher_suite = line2.split()[-1]
        print(index, peer_ip, cipher_suite, sep=', ')

see the question How do I read two lines from a file at a time using python

This just gets the last word of each line, two lines at a time. You would also want to do some error checking like

if "peer" not in line1.split(): 
    raise ValueError(f'Line {index} doesn\'t contain the word "peer", but it should: {line1}')

or trying to parse peer_ip as an IP address

import ipaddress


def is_valid_ip_address(text):
    try:
        ipaddress.ipaddress(text)
        return True
    except ValueError:
        return False


with open("vpn.txt") as f:
    for index, (line1, line2) in enumerate(zip(f, f), start=1):
        peer_ip = line1.split()[-1]
        cipher_suite = line2.split()[-1]

        if not is_valid_ip_address(peer_ip):
            raise ValueError(
                f'Line couldn\'t parse "{peer_ip}" as an IP address on line {index}'
            )

        print(index, peer_ip, cipher_suite, sep=", ")
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
0

you can not use next to a str object.

here is a solution for the exact file structure

with open('vpn.txt', 'r') as fo
    desired_line = ''

    for line in fo:
        list = line.split(" ")
        if "peer" in list:
            desired_line += list[3] + "," + list[6].strip()
        else:
            desired_line += ", " + line.split(' ')[6]
            print(desired_line)
            desired_line = ''
Marios Keri
  • 98
  • 1
  • 8
  • Reading the whole file in memory is strongly discouraged for a number of reasons. Please take the opportunity to train people correctly – Pynchia Nov 11 '19 at 18:59
  • 2
    you can just do `for line in fo`, and you should open files like [`with open('vpn.txt') as fo:`](https://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files) so then you don't have to `.close()` them, it happens automatically. – Boris Verkhovskiy Nov 11 '19 at 19:01
0

You can do it in a easy way using pandas. According to what I see, your requirement is to get 4,6,7th column. I have considered each column is seperated by tab('\t') . You can even use space.
I have used dummy column names. You can use appropriate one.

import pandas as pd
df = pd.read_csv('vpn.txt' , sep = '\t', header = None)
df.columns = ["A", "B", "C", "D", "E", "F", "G"]
OutputData = df[["D","F", "G"]]
OutputData.to_csv('vpn2.txt' , sep= '\t')
Gags08
  • 240
  • 2
  • 9