*nix 方法在','之后乘以行

*nix way to Multiply lines after ','

我有一个文本文件需要调整以便将其输入数据库。

但是,文件的格式虽然一致,但在将它们放入表格时并不是很有用。

allow any 123.123.123.1,2,3 22,443

之后我需要的是

allow any 123.123.123.1 22
allow any 123.123.123.1 443
allow any 123.123.123.2 22
allow any 123.123.123.2 443
allow any 123.123.123.3 22
allow any 123.123.123.3 443

因为文本文件很旧而且超过 1000 行长(我想将它放入我们的数据库的原因之一)手动完成它会非常潮。

是否有使用 sed、tr 等文本处理工具执行此操作的快捷方式?

可以只使用大括号扩展

printf "%s\n" "allow any 123.123.123."{1,2,3}" "{22,443}


allow any 123.123.123.1 22
allow any 123.123.123.1 443
allow any 123.123.123.2 22
allow any 123.123.123.2 443
allow any 123.123.123.3 22
allow any 123.123.123.3 443

可以使用 perl 生成和 运行 括号

perl -ne 's/[^\.\s]+,[,\S]+/{$&}/g;s/[^{}\n]+(?![^{]*})/"$&"/g;print `printf "%s\n" $_`' f

我想出了一个 Awk 脚本如下,来为您完成这项工作。

#!/usr/bin/awk

{
    n1=split(,arr1,".")
    n2=split(arr1[n1],arr2,",")
    n3=split(,arr3,",")

    k=arr1[1]"."arr1[2]"."arr1[3]

    for(i=1;i<=n2;i++) {
        for(j=1;j<=n3;j++) {
            print ,,k"."arr2[i],arr3[j]
        }
    }
}

将它放在一个名为 script.awk 的文件中,运行 作为

awk -f awkscript.awk file
allow any 123.123.123.1 22
allow any 123.123.123.1 443
allow any 123.123.123.2 22
allow any 123.123.123.2 443
allow any 123.123.123.3 22
allow any 123.123.123.3 443

想法是首先将 </code> 的内容拆分为 <code>. 单独得到最后一部分 1,2,3 可以作为 arr1[n] 访问,意思是最后拆分后形成的数组的元素。然后逗号分隔的元素现在被 , 分割并存储在数组 arr2 中,</code> 记录的方式相同。创建变量 <code>k 只是为了将前三个元素存储在第一个 split() 中,即只是 123.123.123

现在对形成的数组元素进行循环以根据需要打印元素。

只是为了 sed 的乐趣(GNU sed 版本 4.2.1):

sed -E -fallow.sed | sort

与allow.sed:

s/^([^\n]+[^,[:digit:]])([[:digit:]]+(,[[:digit:]]+)*),([[:digit:]]+)([^\n]*)$/\n/;
:a;
s/^([^\n,]+[^,[:digit:]])([[:digit:]]+(,[[:digit:]]+)*),([[:digit:]]+)([^\n]*)\n(.*)$/\n\n/;
ta;
s/^([^,]+)\n(.*,.*)$/\n/;
ta;
  • 查找以逗号分隔的数字组。
  • 双线
    • 删除一份中最后一个逗号前的数字
    • 正在删除另一个副本中最后一个逗号后的数字
    • 删除两个副本中的最后一个逗号
  • 从这里开始循环
  • 对第一个换行符之前的内容做同样的事情
  • 保留第一个换行符之后的内容
  • 如果有东西被替换则循环
  • 将换行符(如果有)之间的逗号移到前面
  • 如果有则循环

输出:

allow any 123.123.123.1 22
allow any 123.123.123.1 443
allow any 123.123.123.2 22
allow any 123.123.123.2 443
allow any 123.123.123.3 22
allow any 123.123.123.3 443