通过在 grep 之后组合替换行中的工作

Replace work in line by combining after grep

我需要在执行 grep 并得到结果的最后一行后替换一个词。

这是我的示例文件:

aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 NONE

我需要的是 select 所有包含 'aaa' 的行,得到结果中的最后一行并替换 NONE.

我试过了

cat <file> | grep "aaa" | tail -n 1 | sed -i 's/NONE/ts8/g'

但是没用。

有什么建议吗?

谢谢

使用 tac + awk 解决方案请尝试以下。

tac Input_file | awk '/aaa/ && ++count==1{sub(/NONE/,"ts8")} 1' | tac

一旦您对上述命令感到满意,请尝试执行以下操作,就地保存到 Input_file。

tac Input_file | awk '/aaa/ && ++count==1{sub(/NONE/,"ts8")} 1' | tac > temp && mv temp Input_file

解释: 首先由 tac 以相反的顺序打印 Input_file 然后将其标准输出发送到 awk 作为输入,在第一行(实际上是包含 aaa 的最后一行)中将 NONE 替换为 ts8。简单地打印所有其他行,再次将输出发送到 tac 以使其符合 Input_file 的实际顺序。

为了在单个命令中执行此操作,这应该适用于 awk 的任何版本:

awk 'FNR==NR {if (=="aaa") n=FNR; next} FNR == n {="TS7"} 1' file{,}

aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 TS7

要在同一文件中保存输出,请使用:

awk 'FNR==NR {if (=="aaa") n=FNR; next}
FNR == n {="TS7"} 1' file{,} > file.out && mv file.out file

或使用gnu sed,您可以使用:

sed -i -Ez 's/(.*\naaa[[:blank:]]+[^[:blank:]]+[[:blank:]]+)NONE/ts8/' file

cat file

aaa ts1 ts2
bbb ts3 ts4
aaa ts5 ts6
aaa ts7 ts8

如果想获取开头匹配aaa的最后一行,可以遍历所有行,在END块中,打印最后一次出现的地方,将NONE替换为ts8使用 awk:

awk '=="aaa"{last=[=10=]}END{sub(/NONE/,"ts8",last);print last}' file

部分:

=="aaa" {               # If the first field is aaa
  last=[=11=]                 # Set variable last to the whole line (overwrite on each match)
}
END {                     # Run once at the end                
  sub(/NONE/,"ts8",last)  # Replace NONE with ts8 in the last variable
  print last                 
}
' file

输出

aaa ts7 ts8