如果模式匹配,则将整行替换为上一行的数据(无论是什么)

如果模式匹配,则将整行替换为上一行的数据(无论是什么)

输入文件

Time      Value  Flag
06:15:10  49.95  Actual
00:00:00  0.00  NoValue
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
00:00:00  0.00  NoValue

我必须替换与单词 匹配的整行NoValue。这意味着每当脚本找到带有 的行时NoValue,它都会用上次记录的时间替换整行。

我的结果将显示为,

Time      Value  Flag
06:15:10  49.95  Actual
06:15:10  49.95  Actual
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
06:24:40  49.92  Actual

我努力了

awk 'NR%3==NoValue{ name=$0; next } { print name, $0 }' Inputfile

但它正在合并我不想要的线条。

我的操作系统版本是 Solaris 5.8

答案1

如果条件为真,您awk可以打印上一行:$3 == "NoValue"

awk '$3 == "NoValue" { $0=prev }{prev=$0} 1' file
Time      Value  Flag
06:15:10  49.95  Actual
06:15:10  49.95  Actual
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
06:24:40  49.92  Actual

您可以看到:“如果满足条件,则打印上一行”:https://stackoverflow.com/questions/27740937/print-previous-line-if-condition-is-met

答案2

使用流编辑器 sed,我们可以执行如下操作:

sed -e '
  h
  $!N
  /Actual\n.*NoValue$/ {
    g
    G
  }
  P
  D
' Input file

  • 假设您使用 bourne shell 或其变体,在命令行上运行。
  • sed 代码一次检查两行,如果第一行以“Actual”结尾,第二行以“NoValue”结尾,则在这种情况下删除第二行并在其位置填充第一行。
  • 现在打印第一行(P),删除它(D),并使用现有的模式空间重新运行 sed 代码,前提是它不为空。

答案3

只需两行 sed 即可轻松完成此操作。我们需要做的就是在打印之前将每一行复制到保留空间中。然后,我们可以使用上一行保存的副本来替换以 结尾的任何内容NoValue

#!/bin/sed -f

# for "NoValue" lines, replace with line from hold space
/NoValue$/g

# Store to hold space before printing
h

该脚本足够短,可以传递-e参数:

sed -e '/NoValue$/g' -e h

结果:

Time      Value  Flag
06:15:10  49.95  Actual
06:15:10  49.95  Actual
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
06:24:40  49.92  Actual

这将NoValue用最后一行替换连续的行Actual- 这似乎是对要求的合理解释,尽管问题没有提及此事。

相关内容