sed 匹配字符串的一部分,但只修改特定部分(或 awk,如果可以更简单的话)

sed match part of string, but only modify certain section (or awk, if that could be simpler)

我有一个文件在下面说 tmp.txt。

    root:cDJZp9SHD2KhVgc:0:0:99999:7:::
    bin:*:12821:0:99999:7:::
    daemon:*:12811:0:99999:7:::
    adm:*:12811:0:99999:7:::
    lp:*:12811:0:99999:7:::

我想将第一次出现的 0(仅在第一行)更改为“999999”。可能是这个文件已经修改过,所以第一行如下所示。

root:cDJZp9SHD2KhVgc:999999:0:99999:7:::

所以我试图按照 'root:\w:0' 的方式匹配一些东西,并且只修改 0。有没有办法匹配字符串的这一部分,并指示某个部分(在本例中是0), 只用 sed 修改?或者有更好的方法用 awk 来做吗?

$ sed -r '1s/([a-zA-Z]:)0/9999/' file

root:cDJZp9SHD2KhVgc:99999:0:99999:7:::
bin:*:12821:0:99999:7:::
daemon:*:12811:0:99999:7:::
adm:*:12811:0:99999:7:::
lp:*:12811:0:99999:7:::

如果要将第一行的第三个字段更改为“999999”当且仅当它正好等于“0”时,那么一个简单直接的方法就是使用awk如下:

awk -F: 'BEGIN{OFS=FS} NR==1 &&  == "0" { = "999999"} {print}'

同样可以使用 sed 实现,但它不是那么简单或可读。

(这里 awk 的另一个优点是不必处理 sed 的 -r/-E 选项的 non-standard 性质。)