【问题标题】:Bash Shell - Return substring after second occurrence of certain characterBash Shell - 在第二次出现特定字符后返回子字符串
【发布时间】:2013-03-02 17:54:36
【问题描述】:

我需要在我决定的分隔符之后返回所有内容,但仍然不完全知道如何使用 sed。 我需要做的是:

$ echo "ABC  DE,FG_HI J,123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,," \
  | sed <some regexp>

对于这个例子,返回应该是(子字符串)第二个逗号之后的所有内容:

123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,,

我可以像这样使用 cut 来做到这一点: echo "ABC DE,FG_HI J,123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,," | cut -d',' -f 2-

但有人告诉我 cut 比 sed 慢...

可以请一些拥有它们(并且想要... :) )的大师给我几分钟的时间并给我建议吗? 谢谢! 狮子座

【问题讨论】:

  • 我不知道在这种特定情况下cut 是否比sed 慢,但我可以告诉你cut 不是“比sed 慢”足以使任何实际区别。如果速度这么重要,你就不会在 Bash 中处理它,对吧?
  • 谢谢 Will,如果速度是最重要的,我会在哪里处理它?
  • 如果速度真的很重要,你可以用 C 语言编写它,它可能比使用 cut 快 0.002%,而 cut 又会比 sed 快得多。
  • “如果你需要问,那就够快了”,不过话说,这样看:sed 和 cut 是用 C 编写的。它们都旨在处理各种各样的输入,并产生各种各样的输出。如果您要使用 C 编写工具,那么您可以简化代码并针对您需要处理的特定情况进行优化。这确实会更快。它不会更快 - 值得付出努力。
  • 原来 C 实现比 cut 快得多。在 100000 行输入上快了近 3.7 倍。切的表现如此糟糕,我感到非常惊讶。如果在 C 中实现 4 倍的速度值得花 10 分钟来实现,我会更加惊讶(0.089 秒与 0.024 秒相比很差,但在大多数情况下仍然足够快)。

标签: linux bash sed substring


【解决方案1】:

此方法是通过查找字符第二次出现的索引并使用 bash 子字符串来获得所需的结果

input="ABC  DE,FG_HI J,123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,,"
index=$(($(echo $input| grep -aob '/' | grep -oE '[0-9]+' | awk 'NR==2') + 1))
result=${input:$index}

【讨论】:

    【解决方案2】:

    您也可以尝试在 bash 中进行提取,而根本不产生外部进程:

    $ [[ 'ABC  DE,FG_HI J,123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,,' =~ [^,]*,[^,]*,(.*) ]]
    $ echo "${BASH_REMATCH[@]}"
    123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,,
    

    或

    $ FOO='ABC  DE,FG_HI J,123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,,'
    $ echo ${FOO/+([^,]),+([^,]),}
    

    或

    $ IFS=, read -a FOO <<< 'ABC  DE,FG_HI J,123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,,'
    $ echo ${FOO[@]:2}
    

    (假设这是一次性匹配,而不是遍历文件的内容。)

    【讨论】:

      【解决方案3】:

      根据我的经验,cut 总是比sed 快。

      要使用sed 做你想做的事,你可以使用不匹配的组:

      echo 'ABC  DE,FG_HI J,123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,,' |
        sed -r 's/([^,]*,){2}//'
      

      这会删除前两个字段(如果字段本身不包含逗号),方法是删除非逗号字符 [^,],后跟两次逗号 {2}。

      输出:

      123.XYZ-A1,DD/MM/YYYY HH24:MI:SS,,,
      

      【讨论】:

      • 非常感谢雷神!这正是我想要的 sed。我将尝试使用一些大文件,看看哪个更快。
      猜你喜欢
      • 2019-07-02
      • 2018-02-05
      • 2015-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多