我正在Bourne shell中编写一个例程来命令iptables,它会大量使用“multiport”参数。
iptables允许最多15个对多端口参数的引用。这些引用可以是单独的(计数1)或范围(计数2)。
对于iptables multiport,我需要以可用的方式打破在单个和范围之间混合的一长串端口。
e.g。给出18个参考列表18个单独的端口和2个范围:
21,22,23,24,25,26,27,28,29,30:40,60,61,62,63,64,65:70
我正在尝试找出一种方法将字符串和任何类似的字符串分成最多15个引用的集合,例如15 + 3:
21,22,23,24,25,26,27,28,29,30:40,60,61,62,63
64,65:70
诀窍是:范围不能在不同的行上分割。因此,如果原始输入是:
21,22,23,24,25,26,27,28,29,30:40,60,61,62,63:64,65:70
我需要拆分(14 + 4):
21,22,23,24,25,26,27,28,29,30:40,60,61,62
63:64,65:70
有没有聪明的方法来实现这一点,也许使用awk?
答案 0 :(得分:0)
这是一个简单的Awk脚本,可以在同一行上收集尽可能多的同类项目。
awk -v RS=',' -F : '{ gsub(/\n$/, "") }
NF > 1 { r=(r ? r "," : "") $0;
if (r ~ /([^,]*,){6}/) { print r; r=""; } next }
{ s=(s ? s "," : "") $0;
if (s ~ /([^,]*,){14}/) { print s; s=""; } }
END { if (r && s) {
p = r "," s; if (p !~ /([^,:]*[:,]){15}/) { print p; r=s="" } }
if (r) print r ; if (s) print s }'
更改后的RS
(记录分隔符)表示逗号被拆分,就像它们是换行符一样,并且在这些记录中("行"),冒号被视为字段分隔符。然后我们只检查输入中是否有两个以上的字段,并在打印批次之前收集最多8对或15个单例。
使用输入
21:22,23,24,25,26,27,28,29,30:40,60,61,62,63,64,65:70
打印
21:22,30:40,65:70
23,24,25,26,27,28,29,60,61,62,63,64
您可以在此处播放:http://ideone.com/a3PCzs