【问题标题】:How to extract last field column three only having numbers如何提取最后一个字段第三列只有数字
【发布时间】:2019-02-07 22:17:25
【问题描述】:

我正在尝试获取第三列,特别是只想提取日期,下面是数据的样子。

示例数据集

health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   dpc-syslog-2019.02.04           HJNqQMd_T1qbyHM5HEHGUw   5   1   46559620            0     37.1gb         18.5gb
green  open   syslog-2019.06.23               Q73bPEXUQz64Pt7eh-a3pQ   5   1       4930            0      2.1mb            1mb
green  open   .monitoring-kibana-6-2019.02.04 _5_68NpKStWo3dBFOXZUlw   1   1       8749            0        5mb          2.5mb
green  open   syslog-2019.04.11               e45heIjRTGqO_KHS8He0Ag   5   1         14            0      109kb         54.5kb
green  open   syslog-2019.02.04               -tshSKMAR8GKYnY2KSqn_Q   5   1   19236875            0        5gb          2.5gb
green  open   syslog-2019.05.04               cTgQAcT-QkKklhsKucvotA   5   1         14            0      141kb         70.5kb
green  open   syslog-2019.04.19               CXzRauBZTWu64HB8KTCj5A   5   1         14            0    108.9kb         54.4kb
green  open   syslog-2019.03.02               ap9TDVkIQeGRbTQ9Qpzarg   5   1         14            0    108.3kb         54.1kb
green  open   syslog-2019.03.03               uNcOfR8gSfWYWJgh1Bp9WQ   5   1         14            0    107.6kb         53.8kb

下面是我试图获取日期的内容,但我在下面的命令语法中看到它还有一些我想删除的字符串。

尝试的代码:

[root@host1 ~]# curl -s -XGET http://127.0.0.1:9200/_cat/indices?v | awk '{print $3}'|cut -d. -f1-3 | sed 's/\.//g' | awk -F- '{print $NF}' | head
index
kibana
20190204
20190623
20190204
20190411
20190204
20190504
20190419
20190302
20190303

期望的输出:

20190204
20190623
20190204
20190411
20190204
20190504
20190419
20190302
20190303

也就是说,我只想要数字,只想跳过删除上面代码中的任何字符字符串,如index

我希望这可以使用 awk 或 sed 或 grep 更好、更干净地完成,但只是摆弄实现方式。

感谢您的帮助。

【问题讨论】:

  • 1.你想得到什么输出? 2. 为什么你又使用了 awk 和 cut 以及 sed 和 awk?这不应该是一个 awk 命令吗?
  • @melpomene,我刚刚更新了帖子,虽然我只需要数字
  • 最后一个字段只有数字似乎全为零。
  • @Tiw,这在我的命令输出中,请考虑一下
  • @JamesBrown,看起来帖子的标题具有误导性,我现在试图让它更清楚,很抱歉造成混乱。

标签: awk sed grep


【解决方案1】:

这是一种方式:

$ awk '$3~/[0-9]{4}(\.[0-9]{2}){2}$/{gsub(/^.*-|[^0-9]/,"",$3);print $3}' file
20190204
20190623
20190204
...

解释:

$ awk '$3~/[0-9]{4}(\.[0-9]{2}){2}$/ {  # picking records on regex
    gsub(/^.*-|[^0-9]/,"",$3)           # remove all before last dash and non-digits
    print $3                            # output
}' file

【讨论】:

  • 哇!不错的正则表达式!
  • 确实很棒 +1 ,但是我得到一些空白行和数字,例如 1 仅在行打印中,可以修剪。
  • 空白行来自没有数字的字段,我将在几秒钟内删除它们。你想要 8 位数字还是什么?
  • 现在它期望 $3 以 YYYY.MM-DD 结尾。
  • @JamesBrown,正确 :-)
【解决方案2】:
$ awk 'sub(/.*-/,"",$3){gsub(/\./,"",$3); print $3}' file
20190204
20190623
20190204
20190411
20190204
20190504
20190419
20190302
20190303

【讨论】:

  • 非常漂亮、优雅且兼容的方式:-)
  • 一如既往的好@Ed Morton!
【解决方案3】:

另一种 GNU awk 方式:

awk '$3~/[0-9]{4}/{print gensub(/.*-|[^0-9]*/, "", "g", $3)}'

您可以根据不同的情况微调正则表达式,基本上是准确性与简洁性之间的权衡。

和 GNU sed 解决方案:

sed -E '/(\S*\s+){2}.*[0-9]{4}(\.[0-9]{2}){2}/!d; s/(\S*\s+){2}(\S*\s+).*/\2/g; s/.*-|[^0-9]*//g'

【讨论】:

    【解决方案4】:

    使用tailcuttr

    <infile tail -n+2 | tr -s ' ' | cut -d' ' -f3 | rev | cut -d- -f1 | rev | tr -d .
    

    【讨论】:

    • 不错的带 tr 和 tail 的,cut +1
    【解决方案5】:

    你也可以试试 Perl one-liner

    perl -lane ' if($.>1) { $F[2]=~/.*\-(\d+).(\d+).(\d+)/ and print "$1$2$3" } '
    

    perl -lane ' if($.>1) { $F[2]=~/.*\-(\S+)/ and ($t=$1)=~tr/\.//d and print $t  } ' 
    

    由于标题与日期模式不匹配,因此也可以删除对行号 ($.) 的检查。

    perl -lane ' $F[2]=~/.*\-(\d+).(\d+).(\d+)/ and print "$1$2$3"  '
    

    您的意见

    $ cat pygo.txt
    health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    green  open   dpc-syslog-2019.02.04           HJNqQMd_T1qbyHM5HEHGUw   5   1   46559620            0     37.1gb         18.5gb
    green  open   syslog-2019.06.23               Q73bPEXUQz64Pt7eh-a3pQ   5   1       4930            0      2.1mb            1mb
    green  open   .monitoring-kibana-6-2019.02.04 _5_68NpKStWo3dBFOXZUlw   1   1       8749            0        5mb          2.5mb
    green  open   syslog-2019.04.11               e45heIjRTGqO_KHS8He0Ag   5   1         14            0      109kb         54.5kb
    green  open   syslog-2019.02.04               -tshSKMAR8GKYnY2KSqn_Q   5   1   19236875            0        5gb          2.5gb
    green  open   syslog-2019.05.04               cTgQAcT-QkKklhsKucvotA   5   1         14            0      141kb         70.5kb
    green  open   syslog-2019.04.19               CXzRauBZTWu64HB8KTCj5A   5   1         14            0    108.9kb         54.4kb
    green  open   syslog-2019.03.02               ap9TDVkIQeGRbTQ9Qpzarg   5   1         14            0    108.3kb         54.1kb
    green  open   syslog-2019.03.03               uNcOfR8gSfWYWJgh1Bp9WQ   5   1         14            0    107.6kb         53.8kb
    $ perl -lane ' if($.>1) { $F[2]=~/.*\-(\S+)/ and ($t=$1)=~tr/\.//d and print $t  } ' pygo.txt
    20190204
    20190623
    20190204
    20190411
    20190204
    20190504
    20190419
    20190302
    20190303
    $
    

    【讨论】:

      【解决方案6】:

      请您尝试关注一下。

      awk 'match($3,/[0-9]+\.[0-9]+\.[0-9]+/){val=substr($3,RSTART,RLENGTH);gsub(/\./,"",val);print val}' Input_file
      

      awk '{sub(/.*-/,"",$3);gsub(/\./,"",$3);print $3}'  Input_file
      

      【讨论】:

      • 这可行,但只是看看我们是否可以有更短的方法:-)
      • @pygo,请立即尝试我的第二个解决方案。
      • 第二种解决方案给出错误unexpected newline or end of string
      • @pygo,当然,现在修正了错字。
      【解决方案7】:

      这可能对你有用(GNU sed):

      sed -nr 's/^(\S+\s+){2}\S+(....)\.(..)\.(..)\s+.*/\2\3\4/p' file
      

      第三列的模式匹配,匹配成功时才打印。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-31
        • 2023-01-02
        • 1970-01-01
        • 2019-07-12
        相关资源
        最近更新 更多