如何在bash中的模式(逗号)之后替换第二个模式(点)

时间:2019-11-02 00:00:49

标签: regex unix awk sed

如何替换逗号后的第二个点。

这是我能去的最近的

Task.Run

输出:

echo '0.592922148,0.821504176,1.174.129.731' | xargs -d ',' -n1 echo | sed 's/\([^\.]*\.[^\.]*\)\./\1/' | sed 's/\([^\.]*\.[^\.]*\)\./\1/'

预期输出:

0.592922148
0.821504176
1.174129731

4 个答案:

答案 0 :(得分:3)

您可以使用

sed -e ':a' -e 's/\(\.[^.,]*\)\./\1/' -e 't a'

请参见online sed demo

s='0.592922148,0.821504176,1.174.129.731'
sed -e ':a' -e 's/\(\.[^.,]*\)\./\1/' -e 't a' <<< "$s"

详细信息

  • :a-标签a
  • s/\(\.[^.,]*\)\./\1/-找到一个点并将其捕获到组1中,然后将除点和逗号以外的任何0+字符捕获并捕获,然后仅匹配一个点,并将此匹配项替换为组1中的值(因此,删除第二个匹配的点)
  • t a-如果替换成功,则返回字符串中的a标签位置。

答案 1 :(得分:2)

虽然我认为sed解决方案是您的最佳选择,但由于您同时用sedawk标记了问题,因此awk解决方案非常简单很好地使用split()和基本字符串连接。 (不是很短)例如,您可以这样做:

awk -v OFS=, -F, '{
    for (i=1; i<=NF; i++) {
        n=split ($i, a,".")
        if (n > 2) {
            s=a[1] "." a[2]
            for (j=3; j<=n; j++)
                s = s a[j]
            $i=s
        }
    }
}1'

将字段分隔符和输出字段分隔符定义为','的位置。然后遍历每个字段,检查split()的返回值,将字段分成'.'上的一个数组,分成数组a。如果得到的元素数量大于2,则将前两个元素放回原处,以恢复数量中的第一个'.',然后简单地连接其余字段。末尾的1是打印更新记录的默认“打印记录”。

使用/输出示例

$ echo '0.592922148,0.821504176,1.174.129.731' |
> awk -v OFS=, -F, '{
>     for (i=1; i<=NF; i++) {
>         n=split ($i, a,".")
>         if (n > 2) {
>             s=a[1] "." a[2]
>             for(j=3;j<=n;j++)
>                 s = s a[j]
>             $i=s
>         }
>     }
> }1'
0.592922148,0.821504176,1.174129731

答案 2 :(得分:1)

awk版本:

echo '0.592922148,0.821504176,1.174.129.731' | awk  -F, '{for (i=1;i<=NF;i++) {sub(/\./,"#",$i);gsub(/\./,"",$i);sub(/#/,".",$i);print $i}}'
0.592922148
0.821504176
1.174129731

它将行客栈按,拆分为多个字段。然后,先将.替换为#。然后将.的其余部分替换为空。最后将#替换回.并打印。

编辑

awk -F, '{for (i=1;i<=NF;i++) {sub(/\./,"#",$i);gsub(/\./,"",$i);sub(/#/,".",$i);a=a (i==1?"":",")$i}print a}' file
0.592922148,0.821504176,1.174129731

答案 3 :(得分:1)

请您尝试以下。

echo '0.592922148,0.821504176,1.174.129.731' | 
awk '
BEGIN{
  FS=OFS=","
}
{
  for(i=1;i<=NF;i++){
    ind=index($i,".")
    if(ind){
      val1=substr($i,1,ind)
      val2=substr($i,ind+1)
      gsub(/\./,"",val2)
      $i=val1 val2
    }
  }
  val1=val2=""
}
1' 


说明: 添加上述代码的说明。

echo '0.592922148,0.821504176,1.174.129.731' |   ##Printing values as per OP mentioned and using pipe to send its output as standard input for awk command.
awk '                                            ##Starting awk program from here.
BEGIN{                                           ##Starting BEGIN section of this program here.
  FS=OFS=","                                     ##Setting FS and OFS as comma for each line of Input_file here.
}                                                ##Closing BEGIN BLOCK here.
{
  for(i=1;i<=NF;i++){                            ##Starting a for loop to traverse through fields of line..
    ind=index($i,".")                            ##Checking index of DOT in current field and saving it into ind variable.
    if(ind){                                     ##Checking condition if variable  ind is NOT NULL.
      val1=substr($i,1,ind)                      ##Creating variable val1 from sub-string in current field from 1 to ind value.
      val2=substr($i,ind+1)                      ##Creating variable val2 from sub-string in current field from ind+1 value to till complete length of current field.
      gsub(/\./,"",val2)                         ##Globally substituting DOTs with NULL in val2 variable.
      $i=val1 val2                               ##Re-crearing current field with value of val1 val2.
    }                                            ##Closing BLOCK for if condition.
  }                                              ##Closing BLOCK for for loop.
  val1=val2=""                                   ##Nullifying val1 and val2 variables here.
}                                                ##Closing main code BLOCK here.
1'                                               ##Mentioning 1 will print edited/non-edited line.