linux - 如何使用 sed 或 awk 从字符串中提取多个参数

标签 linux unix sed awk gnuplot

我有一个如下所示的日志文件:

2010/01/12/ 12:00 some un related alapha 129495 and the interesting value 45pts
2010/01/12/ 15:00 some un related alapha 129495 and no interesting value
2010/01/13/ 09:00 some un related alapha 345678 and the interesting value 60pts

我想使用 gnuplot 绘制日期时间字符串与有趣的值。为了做到这一点,我试图将上面的日志文件解析为一个 csv 文件,它看起来像(并非日志中的所有行都有可绘制的值):

2010/01/12/12:00, 45

2010/01/13/14:00, 60

如何使用 sed 或 awk 执行此操作?

我可以提取初始字符,例如:

cat partial.log | sed -e 's/^\(.\{17\}\).*/\1/' 

但是我如何提取最终值?

我一直在尝试这样做,但没有成功!

谢谢

最佳答案

虽然这是一个非常古老的问题,有很多答案,但是您可以使用sedawk (因此与平台无关)。您可以“简单”地使用 gnuplot 来完成此操作(即使使用 OP 问题当时的版本:gnuplot 4.4.0,2010 年 3 月)。

但是,从您的示例数据和描述来看,尚不清楚是否具有兴趣值(value)

  1. 严格位于第 12 列或
  2. 始终位于最后列或
  3. 可以在任何列中,但始终尾随 pts

对于所有 3 种情况,都有仅使用 gnuplot(因此与平台无关)的解决方案。 假设列分隔符是空格。

ad 1. 最简单的解决方案:使用 u 1:12,gnuplot 将简单地忽略非数字和列值,例如例如 45pts 将被解释为 45

ad 2. 和 3. 如果您将最后一列提取为字符串,如果您想通过 real() 将非数字值转换为 float ,gnuplot 将失败并停止。因此,您必须通过自己的函数 isNumber() 来测试列值是否至少以数字开头,从而可以通过 real() 进行转换。如果字符串不是数字,您可以将值设置为 1/0NaN。然而,在早期的 gnuplot 版本中,线(点)图的线条将被中断。 而在较新的 gnuplot 版本 (>=4.6.0) 中,您可以将值设置为 NaN 并通过 set datafile Missing NaN 避免中断,但这在 gnuplot 中不可用4.4. 此外,在 gnuplot 4.4 中,NaN 只是设置为 0.0 (GPVAL_NAN = 0.0)。 您可以使用下面也使用的 "trick" 来解决此问题。

数据: SO7353702.dat

2010/01/12/ 12:00 some un related alapha 129495 and the interesting value 45pts
2010/01/12/ 15:00 some un related alapha 129495 and no interesting value
2010/01/13/ 09:00 some un related alapha 345678 and the interesting value 60pts
2010/01/15/ 09:00 some un related alapha 345678 62pts and nothing
2010/01/17/ 09:00 some un related alapha 345678 and nothing
2010/01/18/ 09:00 some un related alapha 345678 and the interesting value 70.5pts
2010/01/19/ 09:00 some un related alapha 345678 and the interesting value extra extra 64pts
2010/01/20/ 09:00 some un related alapha 345678 and the interesting value 0.66e2pts

脚本:(适用于 gnuplot>=4.4.0,2010 年 3 月)

### extract numbers without external tools
reset
FILE = "SO7353702.dat"

set xdata time
set timefmt "%Y/%m/%d/ %H:%M"
set format x "%b %d"
isNumber(s) = strstrt('+-.',s[1:1])>0 && strstrt('0123456789',s[2:2])>0 \
              || strstrt('0123456789',s[1:1])>0

# Version 1:
plot FILE u 1:12 w lp pt 7 ti "value in the 12th column"
pause -1

# Version 2:
set datafile separator "\t"
getLastValue(col) = (s=word(strcol(col),words(strcol(col))), \
                     isNumber(s) ? (t0=t1, real(s)) :  (y0))
plot t0=NaN FILE u (t1=timecolumn(1), y0=getLastValue(1), t0) : (y0) w lp pt 7 \
        ti "value in the last column"
pause -1

# Version 3:
getPts(s) = (c=strstrt(s,"pts"), c>0 ? (r=s[1:c-1], p=word(r,words(r)), isNumber(p) ? \
            (t0=t1, real(p)) : y0) : y0)
plot t0=NaN FILE u (t1=timecolumn(1),y0=getPts(strcol(1)),t0):(y0) w lp pt 7 \
            ti "value anywhere with trailing 'pts'"
### end of script

结果:

版本 1:

enter image description here

版本 2:

enter image description here

版本 3:

enter image description here

关于linux - 如何使用 sed 或 awk 从字符串中提取多个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7353702/

相关文章:

unix - 删除 CSV 文件中的一系列行,除了给定范围之间的一行

regex - 捕获两个标记之间的文本

c++ - 如何在 Linux 上调试 native 代码时自动附加到多个子进程?

linux - 在 R 中执行 library(package) 报告包是为 i386 构建的,它可以安装在 x86_64 系统上吗?

c - C语言编程中如何判断文件/目录是否隐藏

c - 结构中的 "s"是什么意思?

linux - Fortran 中子目录的标准输入重定向

ruby - 如何在 ruby​​/bash 脚本中杀死生成的子进程

linux - 比较 Bash 中按字母顺序排列的字符串、测试与双括号语法

regex - 如何更改sed中的日期格式?