通过IP扩展端口范围

时间:2020-04-22 11:42:44

标签: python python-3.x linux awk scripting

嗨,我需要一些帮助,所以我有一个包含以下信息的文件;

IP,Ports,count
"192.168.0.1","80 8980 6789 443 4778 3556 7778 4432 5674 7786 2234 6678 33245 7788 3332 6678 3322 5432 5567",19
"192.168.0.2","80 8980 6789 443 4778 3556 7778 4432 5674 7786 2234 6678 33245 7788 3332 6678 3322 5432 5567",19
"192.168.0.3","80 8980 6789 443 4778 3556 7778 4432 5674 7786 2234 6678 33245 7788 3332 6678 3322 5432 5567",19
"192.168.0.4","80 8980 6789 443 4778 3556 7778 4432 5674 7786 2234 6678 33245 7788 3332 6678 3322 5432 5567",19

我想将端口拆分为5个左右的范围,对于新文件及其IP的每个文件。

预期结果。

IP,Ports
192.168.0.1 80,8980,6789,443,4778
192.168.0.1 3556,7778,4432,5674,7786
192.168.0.1 2234,6678,33245,7788,3332
192.168.0.1 6678,3322,5432,5067
192.168.0.2 80,8980,6789,443,4778
192.168.0.2 3556,7778,4432,5674,7786
192.168.0.2 2234,6678,33245,7788,3332
192.168.0.2 6678,3322,5432,5067
192.168.0.3 80,8980,6789,443,4778
192.168.0.3 3556,7778,4432,5674,7786
192.168.0.3 2234,6678,33245,7788,3332
192.168.0.3 6678,3322,5432,5067
192.168.0.4 80,8980,6789,443,4778
192.168.0.4 3556,7778,4432,5674,7786
192.168.0.4 2234,6678,33245,7788,3332
192.168.0.4 6678,3322,5432,5067

说实话,我不知道该怎么做或从哪里开始。请协助。

无论是AWK还是python都可以,只要向我解释一下脚本/单行代码是做什么的,这样我就可以尝试使用它。

2 个答案:

答案 0 :(得分:2)

对于Python,您可以执行以下操作:

演示:

from csv import DictReader, DictWriter

# Given attribute to https://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks/312464#312464
def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in range(0, len(lst), n):
        yield lst[i:i + n]

# Open both input and output files
with open("data.csv") as f, open("output.csv", mode="w", newline='') as o:

    # Create reading and writing objects
    reader = DictReader(f)
    writer = DictWriter(o, fieldnames=["IP", "Ports"])

    # Write headers
    writer.writeheader()

    # Go through each line from reader object
    for line in reader:

        # Split ports by whitespace into a list of ports
        ports = line["Ports"].split()

        # Go through each chunk(n = 5) of ports
        for port_chunk in chunks(ports, 5):

            # Write row to output CSV file
            row_dict = {"IP": line["IP"], "Ports": ",".join(port_chunk)}
            writer.writerow(row_dict)

output.csv

IP,Ports
192.168.0.1,"80,8980,6789,443,4778"
192.168.0.1,"3556,7778,4432,5674,7786"
192.168.0.1,"2234,6678,33245,7788,3332"
192.168.0.1,"6678,3322,5432,5567"
192.168.0.2,"80,8980,6789,443,4778"
192.168.0.2,"3556,7778,4432,5674,7786"
192.168.0.2,"2234,6678,33245,7788,3332"
192.168.0.2,"6678,3322,5432,5567"
192.168.0.3,"80,8980,6789,443,4778"
192.168.0.3,"3556,7778,4432,5674,7786"
192.168.0.3,"2234,6678,33245,7788,3332"
192.168.0.3,"6678,3322,5432,5567"
192.168.0.4,"80,8980,6789,443,4778"
192.168.0.4,"3556,7778,4432,5674,7786"
192.168.0.4,"2234,6678,33245,7788,3332"
192.168.0.4,"6678,3322,5432,5567"

答案 1 :(得分:2)

请您尝试以下操作(在显示的示例中经过测试和编写)。

awk -F'"|","' -v lines=$(wc -l < Input_file) '
BEGIN{
  print "IP,ports"
}
FNR>1{
  num=split($3,array," ")
  for(i=1;i<=num;i++){
    if(i==1){ printf $2 OFS }
    printf("%s%s",array[i],i%5==0||i==num?ORS:FNR==lines && i==num?ORS:",")
    if(i%5==0){ printf $2 OFS }
  }
}' Input_file

说明: 在此处添加以上内容的详细说明。

awk -F'"|","' -v lines=$(wc -l < Input_file) '                                  ##Starting awk program from here.
BEGIN{                                                                          ##Starting BEGIN section of this program.
  print "IP,ports"                                                              ##Printing headers here.
}
FNR>1{                                                                          ##Checking condition if current line number is greater than 1st line.
  num=split($3,array," ")                                                       ##Splitting 3rd field into an array with delimiter space.
  for(i=1;i<=num;i++){                                                          ##Traversing through all elements of array here.
    if(i==1){ printf $2 OFS }                                                   ##if its first element of array then print 2nd field of line and OFS.
    printf("%s%s",array[i],i%5==0||i==num?ORS:FNR==lines && i==num?ORS:",")     ##Printing array value along with condition if its 5 element or number of total elements equals i then print new line OR current line number equal to lines OR i equals to num then print new line OR print comma.
    if(i%5==0){ printf $2 OFS }                                                 ##If its 5th element then print current line 2nd field with space
  }
}' Input_file                                                                   ##mentioning Input_file name here.