我的文件中有以下几行
$ cat test.txt
69|1074330570|1,sip:+121345633210x3Bverstat=TN-Validation-Passed|tel:+12134565534|0
69|1077822111|2,;tel:+2223120011~sip:[email protected];|sip:[email protected]|0
69|1077988012|1,sip:+121510016070x3Bverstat=TN-Validation-Passed|tel:+136965339510x3Bnpd|0
我想用电话号码替换文件中的第三列和第四列,如下所示:
69|1074330570|2134563321|2134565534|0
69|1077822111|2223120011|3123120022|0
69|1077988012|2151001607|3696533951|0
好的部分是所有文件在第三列和第四列中都会有一个“+”。现在困难的部分是,有时我们会得到第一行第三列中注意到的 11 位数字 (121345633210),有时“+”后没有添加“1”。因此,如果加号后面有 1,则排除 1。否则,从“+”号后面开始长度。同样,如果有 11 位数字,只需子串 10。此外,如果有超过 1 个数字(如第 2 行),我只需要选取“+”号后面的第一个数字,例如 2223120011,而不是 2223120051。
我尝试了以下方法
awk -F"|" 'BEGIN {FS="+"}{print substr($3,2,10)}' test.txt
但它为第二行提供了不正确的值,因为它需要在“+”号之后开始。
当前代码的问题:
-F"|"
两者FS="+"
都定义了输入字段分隔符,因此从技术上讲,您应该选择其中之一,但不能同时选择两者;在这种情况FS="+"
下优先(即被-F"|"
忽略)-F"|"
,但也将其定义为输出字段分隔符(推荐:BEGIN { FS=OFS="|"}
awk
字符串函数的某种组合(例如,split()
,match()
,index()
,substr()
)进一步解析第三/第四字段假设/理解:
+
+
始终是 10 位或 11 位数字+
,那么我们只对第一个+
感兴趣(例如,我们不必根据tel
or进一步解析sip
)一个
awk
想法:笔记:
这会生成:
您可以使用这个
awk
解决方案:使用 GNU awk 可以
gensub()
:或使用任何 awk:
对于您显示的示例,请尝试以下 GNU
awk
代码。说明:为上述代码添加详细说明。
awk
的match
函数在其中使用正则表达式,这会创建捕获组,稍后我们可以使用它们来获取所需的输出。^([^|]*\|[^|]*\|)[^+]*\+1*([0-9]+)[^|]*(\|)[^+]*\+1*([0-9]+)[^|]*(\|.*$)
在函数内部使用正则表达式match
。0
使用此处删除第二个和第四个捕获组的最后一个sub
。