在所有多行中将整列替换为新值

Sam*_*Sam 6 regex linux awk replace substr

我的文件中有以下几行

$ cat test.txt
69|1074330570|1,sip:+121345633210x3Bverstat=TN-Validation-Passed|tel:+12134565534|0
69|1077822111|2,;tel:+2223120011~sip:+2223120051@vzpps.com;|sip:+13123120022@vzpps.com|0
69|1077988012|1,sip:+121510016070x3Bverstat=TN-Validation-Passed|tel:+136965339510x3Bnpd|0
Run Code Online (Sandbox Code Playgroud)

我想用电话号码替换文件中的第三列和第四列,如下所示:

69|1074330570|2134563321|2134565534|0
69|1077822111|2223120011|3123120022|0
69|1077988012|2151001607|3696533951|0
Run Code Online (Sandbox Code Playgroud)

好的部分是所有文件在第三列和第四列中都会有一个“+”。现在困难的部分是,有时我们会得到第一行第三列中注意到的 11 位数字 (121345633210),有时“+”后没有添加“1”。因此,如果加号后面有 1,则排除 1。否则,从“+”号后面开始长度。同样,如果有 11 位数字,只需子串 10。此外,如果有超过 1 个数字(如第 2 行),我只需要选取“+”号后面的第一个数字,例如 2223120011,而不是 2223120051。

我尝试了以下方法

awk -F"|"  'BEGIN {FS="+"}{print substr($3,2,10)}' test.txt
Run Code Online (Sandbox Code Playgroud)

但它为第二行提供了不正确的值,因为它需要在“+”号之后开始。

anu*_*ava 5

您可以使用这个awk解决方案:

awk '
function extphone(s) {
   sub(/^[^+]*\+1?/, "", s)  # remove all text before + then + and optional 1
   return substr(s, 1, 10)   # extract first 10 characters now
}
BEGIN {FS=OFS="|"}
{
   $3 = extphone($3)
   $4 = extphone($4)
} 1' file

69|1074330570|2134563321|2134565534|0
69|1077822111|2223120011|3123120022|0
69|1077988012|2151001607|3696533951|0
Run Code Online (Sandbox Code Playgroud)


mar*_*rkp 4

当前代码的问题:

  • -F"|"两者FS="+"都定义了输入字段分隔符,因此从技术上讲,您应该选择其中之一,但不能同时选择两者;在这种情况FS="+"下优先(即被-F"|"忽略)
  • 由于总体要求是“替换”第三列和第四列,因此您需要保留-F"|",但也将其定义为输出字段分隔符(推荐:BEGIN { FS=OFS="|"}
  • 然后查看使用awk字符串函数的某种组合(例如,split(), match(), index(), substr())进一步解析第三/第四字段

假设/理解:

  • 第三/第四字段总是有一个+
  • 后面的字符串+始终是 10 位或 11 位数字
  • 如果第三/第四个字段有多个+,那么我们只对第一个 +感兴趣(例如,我们不必基于tel或进一步解析sip进一步解析)
  • 看来我们正在处理北美电话号码格式(例如,我们不必担心其他国家/地区的不同电话号码格式)

一个awk想法:

awk '
BEGIN { FS=OFS="|" }
      { for (i=3; i<=4; i++) {                         # loop through 3rd and 4th fields
            split($i,a,"+")                            # split on "+"
            d1 = substr(a[2],1,1)                      # get 1st digit after the "+"
            $i = substr(a[2],(d1==1 ? 2 : 1),10)       # redefine ith field based on value of 1st digit
        }
      }
1                                                      # print current line
' test.txt
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 该逻辑是基于我们只需要处理北美电话号码格式(10 位/11 位,国家代码 = 1)的假设进行硬编码的

这会生成:

69|1074330570|2134563321|2134565534|0
69|1077822111|2223120011|3123120022|0
69|1077988012|2151001607|3696533951|0
Run Code Online (Sandbox Code Playgroud)