【问题标题】:Print only the letters after matching in bash在bash中匹配后只打印字母
【发布时间】:2021-01-22 10:30:31
【问题描述】:

我想在 bash 中从 2021-01-19T12:40:56.671773769Z 打印 12:40:56。我尝试使用 sed 和 awk。但它不起作用。这就是我用 sed 尝试过的。

get_time= docker inspect "containerid" | grep `cut -d -f1 4`
#which give output as 2021-01-19T12:40:56.671773769Z
start= $get_time | grep `sed -n -e 's/^.*T: //.'`

我在这里做错了什么?任何帮助将不胜感激。

【问题讨论】:

  • 另外,分配变量的方式没有意义。如果你真的要这样写,get_timestart 会是空的,你也会得到一个错误信息。请至少在此处发布代码之前使代码没有语法错误。
  • 将其复制/粘贴到 shellcheck.net 并修复它告诉您的问题,如果您还有问题,请在此处发布问题。
  • 我投票结束这个问题,因为它还没有通过 shellcheck。

标签: linux bash shell awk sed


【解决方案1】:

对于您展示的示例,最简单的解决方案是将分隔符设为T. 并打印第二个字段,完全基于您展示的示例。

echo "$get_time" | awk -F'[T.]' '{print $2}'

第二个解决方案:使用match 函数尝试跟随,使用正则表达式来匹配这里的时间值。

echo "$get_time" | 
awk 'match($0,/T([0-9]{2}:){2}[0-9]{2}/){print substr($0,RSTART+1,RLENGTH-1)}'

第三种解决方案:在此处根据需要使用gsub 函数执行全局替换。

echo "$get_time" | awk '{gsub(/.*T|\..*/,"")} 1'

注意:所有 3 个解决方案均仅在 GNU awk 中使用所示示例编写和测试。

【讨论】:

  • 没有所谓的输入文件。我应该用什么来代替它?
  • @Siddharth,没问题,将其作为变量值传递给awk 然后:)
【解决方案2】:

假设2021-01-19T12:40:56.671773769Zget_time变量的值,可以使用sed

start=$(sed -n 's/.*T\(.*\)\..*/\1/p' <<< "$get_time")

这里,

  • -n - 禁止默认行输出
  • .*T\(.*\)\..* 匹配任何文本,然后是 T,然后将直到最后一个 . 的任何文本捕获到第 1 组 (\1),然后 \. 匹配一个点,.* 匹配字符串的其余部分, 和
  • \1 - 用第 1 组值替换整个匹配字符串
  • p - 打印替换结果。

online demo

s='2021-01-19T12:40:56.671773769Z'
sed -n 's/.*T\(.*\)\..*/\1/p' <<< "$s"

【讨论】:

    【解决方案3】:

    使用extglob 的纯 bash 解决方案:

    s='2021-01-19T12:40:56.671773769Z'
    shopt -s extglob
    echo "${s//@(*T|.*)}"
    
    12:40:56
    

    或者没有extglob:

    s='2021-01-19T12:40:56.671773769Z'
    p="${s#*T}"
    echo "${p%%.*}"
    
    12:40:56
    

    或单行grep:

    grep -Eo '([0-9]{2}:){2}[0-9]{2}' <<< "$s"
    
    12:40:56
    

    【讨论】:

      【解决方案4】:

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

      sed -En 's/.*(..:..:..).*/\1/p' file
      

      日期的模式匹配并删除其他所有内容。

      【讨论】:

        【解决方案5】:

        我会使用AWK 以下方式:

        echo '2021-01-19T12:40:56.671773769Z' | awk 'BEGIN{FPAT="[0-9][0-9]:[0-9][0-9]:[0-9][0-9]"}{print $1}'
        

        输出

        12:40:56
        

        解释:awk 当给定 FPAT 时查找行中的匹配项并将后续匹配项分配到列中,因为有一个匹配项在第一列结束,然后是 printed。

        我想指出,您的时间戳看起来对于年月日具有固定宽度,如果是这种情况,更简单的解决方案可能是只采用子字符串。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-04-29
          • 1970-01-01
          • 2013-07-04
          • 2013-01-06
          • 1970-01-01
          • 1970-01-01
          • 2022-06-15
          • 2018-06-08
          相关资源
          最近更新 更多