【问题标题】:how to print last part of a string in shell script如何在shell脚本中打印字符串的最后一部分
【发布时间】:2017-06-29 08:58:56
【问题描述】:

我有这行:

102:20620453:d=2017021012:UGRD:10 m above ground:15 hour fcst::lon=79.500000,lat=9.000000,val=-5.35

现在我只想从这一行打印值 -5.35,而不是别的。

我还希望这个命令能够从这一行中提取 -7.04 而没有别的。

102:20620453:d=2017021012:UGRD:10 m above ground:15 hour fcst::lon=280.500000,lat=11.000000,val=-7.04

我已经阅读了其他堆栈溢出问题,但它们似乎并没有完全理解我要寻找的内容。我注意到他们做了 awk 或 sed。我应该做哪些事情才能在 val= 之后仅提取上述行的一部分?

【问题讨论】:

  • val 是否绝对肯定是每一行中的最后一个字段——不仅适用于当前版本的日志字符串,还适用于所有未来版本?就个人而言,我对做出这样的假设持谨慎态度。
  • 顺便说一句——您是一次处理一行,还是一次处理整个文件?它在性能上有很大的不同:您最好将awk 用于大流,而如果您一次一行,使用 bash 内置将节省启动外部进程的(显着)成本。 (也就是说:如果你只是在每行日志记录中运行一个 awk 副本,anubhava 的答案比我的要慢得多,但是使用 anubhava 的 awk 并给它 20MB 的日志来一次解析比使用要快得多循环中的 bash 内置字符串操作)。

标签: string shell awk


【解决方案1】:

不需要awksed 或任何其他外部工具:bash 有自己的内置正则表达式支持,通过=~ 运算符到[[ ]]BASH_REMATCH 数组(填充匹配的内容)。

val_re='[, ]val=([^ ]+)'
line='102:20620453:d=2017021012:UGRD:10 m above ground:15 hour fcst::lon=79.500000,lat=9.000000,val=-5.35'
[[ $line =~ $val_re ]] && echo "${BASH_REMATCH[1]}"

也就是说,如果您真的想要删除直到并包括字符串 val= 的所有内容(因此如果将来将其他值添加到格式中,您的代码会中断),你也可以这样做:

val=${line##*val=}  # assign everything from $line after the last instance of "val=" to val

这里的语法是parameter expansion。另见BashFAQ #100: How do I do string manipulations in bash?

【讨论】:

    【解决方案2】:

    您可以使用带有字段分隔符的 awk 作为 = 并打印最后一个字段:

    awk -F'=' '{print $NF}' <<< "$str"
    
    -5.35
    

    【讨论】:

      【解决方案3】:

      这将从末尾搜索字符串 val= 并在此之后给出任何内容

      str='102:20620453:d=2017021012:UGRD:10 m above ground:15 hour fcst::lon=79.500000,lat=9.000000,val=-5.35'
      
      echo "$str" | grep -Po '(?<=val=).*'
      

      answer 仅适用于 GNU grep

      【讨论】:

      • ...grep保证提供的功能的完整列表在pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html 中给出。并不是说不可以编写依赖于扩展的 StackOverflow 答案,但是当答案仅适用于 GNU grep、现代 BSD grep 或其他特定实现时,应该调用它。 (实际上,即使使用 GNU grep,-P 支持也取决于编译时标志,这些标志只能在具有 libpcre 的系统上启用)。
      • ...re: echo $str,参见BashPitfalls #14,或通过shellcheck.net 运行您的代码,然后点击警告中的链接到SC2086
      • 您已更正了引用问题,但您的回答仍未提及使用 -P 需要 GNU grep。将正则表达式包含在 "..." 而不是 '...' 中是不明智的,除非您有意嵌入 shell 变量引用。 [^$] 在这里没有意义(它匹配任何字符。except (^) 一个 literal $) - 你可能只是指.。最后。请format your code properly.
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-14
      • 2014-08-05
      • 1970-01-01
      • 2017-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多