【问题标题】:SPLITING PORT RANGES IN A NEW LINE WITH IP使用 IP 将端口范围划分为新系列
【发布时间】:2020-04-22 11:42:44
【问题描述】:

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

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 中任何一个都可以,只需向我解释一下脚本/单行代码的作用,以便我可以尝试使用它。

【问题讨论】:

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


【解决方案1】:

您能否尝试以下操作(已在所示示例中测试和编写)。

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.

【讨论】:

  • 这很好用,你能解释一下吗,还有你有资源可以让我去学习 AWK。 :)
  • @n00b,我刚刚在我的答案中添加了详细级别的解释,用于学习 awk 我想说你可以看到这个链接一次 stackoverflow.com/tags/awk/info 我也参考过的地方可能对你有帮助。
  • @n00b,任何与解释有关的问题,请让我知道会尽力帮助,干杯。
【解决方案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)

输出.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"

【讨论】:

  • python 脚本出现一些错误,但我会看看它,不过谢谢你的帮助!!
  • @n00b 真的吗?这对我来说可以。你得到什么样的错误?如果您使用 Windows,则需要将完整路径传递给文件。
猜你喜欢
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 2020-04-29
  • 2019-10-29
  • 2019-01-09
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
相关资源
最近更新 更多