将FQDN和ip列表转换为两列CSV



我想要一个这样的列表:

example.com
1.2.3.4
ftp.example.com
2.3.4.5
3.4.5.6
www.example.com
4.5.6.7
5.6.7.8
6.7.8.9

并解析为逗号分隔的CSV格式,以便在流行的电子表格程序中打开时,父fqdn位于a列,子ip位于b列。

我想使用本地的Linux二进制文件,这样我就可以嵌入到现有的BASH脚本中。

欢迎任何帮助,提前感谢。

这可能适合您(GNU sed):

sed -r '/[[:alpha:]]/h;//d;G;s/(.*)n(.*)/2,1/' file

如果该行包含字母字符,即是地址,将其存储在保持空间中,然后删除它。否则,将地址追加到当前行,然后交换两个字段,用,替换换行符并打印

编辑:我看错了问题。下面我的解决方案打印主机名,然后是IP地址列表,而不是主机名+ IP地址对列表。

我将使用以下逻辑:对于每一行输入,
  1. 如果文本包含IP地址以外的内容,则打印一个新的行字符,然后打印文本。不打印第一行文本的新行字符。
  2. 否则,打印逗号,然后再打印文本

例子:

Perl:

perl -npe 'chomp;  $_ = /[^d.]/ ? "$p$_" : ",$_"; $p="n"'
Bash

:

#!/bin/bash
while read line; do
    if [[ $line =~ [^0-9.] ]]; then
        echo -en "$pre$line"
    else
        echo -n ",$line"
    fi
    pre="n"
done

sed用于单独行上的简单替换,仅此而已。如果您使用的是sed结构而不是s、g和p(带-n),那么您使用的是在20世纪70年代中期awk发明时已经过时的结构。

$ awk '/^[[:alpha:]]/{f=$0;next} {print f","$0}' file
example.com,1.2.3.4
ftp.example.com,2.3.4.5
ftp.example.com,3.4.5.6
www.example.com,4.5.6.7
www.example.com,5.6.7.8
www.example.com,6.7.8.9

注意这是多么清晰和简单,因为awk有变量,而sed没有。凑巧的是,如果您关心的话,它也比sed方法稍微简短一些,而且我敢打赌,如果您的文件很大,它的执行速度会更快。它也可以移植地工作在所有操作系统上的所有POSIX(由于POSIX字符类)awks上,它不是特定于gnu的。

为了解决下面的评论,如果您希望每个FQDN的所有IP地址都在一行上,那么这是一种方法:

$ cat tst.awk
/^[[:alpha:]]/ { recs[++numFqdns] = $0; next }
{ recs[numFqdns] = recs[numFqdns] "," $0 }
END {
    for (fqdnNr=1; fqdnNr<=numFqdns; fqdnNr++) {
        print recs[fqdnNr]
    }
}
$ awk -f tst.awk file
example.com,1.2.3.4
ftp.example.com,2.3.4.5,3.4.5.6
www.example.com,4.5.6.7,5.6.7.8,6.7.8.9

或者,从skmrx的答案直接翻译这个shell脚本:

while read line; do
    if [[ $line =~ [^0-9.] ]]; then
        echo -en "$pre$line"
    else
        echo -n ",$line"
    fi
    pre="n"
done

:

awk '{
    if (/[^0-9.]/) {
        printf "%s%s", pre, $0
    }
    else {
        printf ",%s", $0
    }
    pre="n"
}'

,但是你从来不会在awk中写它,相反,在awk中写这种逻辑的惯用方法是:

awk '{ printf "%s%s", (/[^0-9.]/ ? pre : ""), $0; pre=RS }'

,您可以添加END{print ""}来打印shell脚本中缺少的最后一个换行符。

最新更新