用sed替换四次

fty*_*ty4 3 sed string text-processing

我想替换这个字符串中的第二个、第三个、第四个和第五个点

2019-03-17T11:32:28.143343Z;1234.5678;901.234;567.89012;3456.78;192.168.0.1
Run Code Online (Sandbox Code Playgroud)

用逗号,得到这个结果:

2019-03-17T11:32:28.143343Z;1234,5678;901,234;567,89012;3456,78;192.168.0.1
Run Code Online (Sandbox Code Playgroud)

第一个逗号和第六个(以及之后的任何一个)应该保持不变。

我找到了这个命令,我可以多次执行它(但可能不是最佳实践):

echo "$tmp" | sed 's/\./\,/2'
Run Code Online (Sandbox Code Playgroud)

如何在一个命令中完成此操作?

Kus*_*nda 8

您的数据由六个;分隔的字段组成,您想用逗号替换字段 2 到 5(不是 1 或 6)中的点。

这是最容易完成的awk

awk -F ';' 'BEGIN { OFS=FS } { for (i=2; i<=5; ++i) gsub("\\.", ",", $i); print }' file
Run Code Online (Sandbox Code Playgroud)

使用给出的示例数据,这会产生

2019-03-17T11:32:28.143343Z;1234,5678;901,234;567,89012;3456,78;192.168.0.1
Run Code Online (Sandbox Code Playgroud)

代码简单地迭代;每个输入行的-delimited 字段,并调用在循环迭代的各个字段上gsub()进行全局搜索和替换(就像你在 withs/\./,/gy/./,/in 中所做的那样sed)。

然后打印修改后的行。

-F选项将输入字段分隔符设置为分号,我们使用该BEGIN块还将输出字段分隔符设置为相同的值(否则您将获得空格分隔的字段)。


使用sed,你可能会做类似的事情

sed 's/\./,/2; s/\./,/2; s/\./,/2; s/\./,/2' file
Run Code Online (Sandbox Code Playgroud)

即,将第二个点替换四次(哪个是第二个点会随着每次替换而改变,因为您替换了它们)。然而,这确实假设每个字段中的值数量保持不变。

要解决此问题,以防您在某个时候在一个字段中有两个以上以点分隔的内容,您可以执行以下操作

sed 'h; s/^[^;]*;//; s/;[^;]*$//; y/./,/; G;H;x; s/;[^\n]*\n/;/; s/\n.*;/;/' file
Run Code Online (Sandbox Code Playgroud)

简而言之,这些命令做

  1. 将原始行复制到保留空间。
  2. 删除模式空间中的第一个和最后一个字段。
  3. 将模式空间中的所有点更改为逗号(这是y命令)。所有应该变成逗号的点现在都已更改。现在我们必须从模式空间中的中间位和保持空间中的原始数据重新组合行。
  4. 使(与G;H;x)模式空间包含

    1. 原始字符串,后跟换行符,
    2. 修改后的中间位,后跟换行符
    3. 又是原来的字符串。
  5. 所以现在模式空间包含三行。删除除第一行的第一个字段和换行符以外的所有内容,并将删除的位替换为;.

  6. 对最后一行做类似的事情,即删除(现在单独的)换行符和最后一行的所有内容;,并替换为;.

  7. 完毕。

或者你可以只使用awk代码。