我想要这样的列表:
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脚本进行烘焙。
欢迎任何帮助,并提前致谢。
答案 0 :(得分:1)
编辑:我错误地阅读了这个问题。我的解决方案下面打印主机名,然后打印IP地址列表,而不是主机名+ IP地址对列表。
我会使用以下逻辑:对于每行输入,
示例:
的Perl:
perl -npe 'chomp; $_ = /[^\d.]/ ? "$p$_" : ",$_"; $p="\n"'
击:
#!/bin/bash
while read line; do
if [[ $line =~ [^0-9.] ]]; then
echo -en "$pre$line"
else
echo -n ",$line"
fi
pre="\n"
done
答案 1 :(得分:1)
这可能适合你(GNU sed):
sed -r '/[[:alpha:]]/h;//d;G;s/(.*)\n(.*)/\2,\1/' file
如果该行包含字母字符,即地址,则将其存储在保留空间中,然后将其删除。否则,将地址附加到当前行,然后交换两个字段,用,
替换换行并打印。
答案 2 :(得分:1)
sed用于单个行上的简单替换,即全部。如果你使用s,g和p以外的sed结构(带-n)那么你使用的结构在20世纪70年代中期发明时已经过时了。
$ 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
Alterantively,这个shell脚本的直接awk翻译来自skmrx的回答:
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脚本中缺少的最终换行符。