【问题标题】:How to remove characters before and including an underscore?如何删除包含下划线之前的字符?
【发布时间】:2015-09-01 03:36:30
【问题描述】:

请在 bash 脚本中执行以下操作的有效方法是什么?

var="fooo_barrrr"

请问,删除“_”之前和包括“_”之前的所有字符以便 var 变为“barrrr”的最佳方法是什么?

【问题讨论】:

  • 如果你有多个_怎么办?你想保留字符串的哪一部分?

标签: linux string bash unix awk


【解决方案1】:

使用Parameter Expansion

$ var="fooo_barrrr"
$ echo ${var#*_}
barrrr

要更改 var 本身,var=${var#*_}

请注意,这会删除第一个 _

$ var="fooo_barrr_r"
$ echo ${var#*_}
barrr_r

如果您想删除最后一个,则需要改用##

$ var="fooo_barrr_r"
$ echo ${var##*_}
r

查看一些替代方案:

sed:

$ sed 's/^[^_]*_//' <<< "foo_barrrr_r"
barrrr_r

awk:

$ awk 'gsub(/^[^_]*_/,"")1' <<< "foo_barrrr_r"
barrrr_r

grep:

$ grep -oP '[^_]*_\K.*' <<< "foo_barrrr_r"
barrrr_r

在所有情况下,要将新值存储在同一个变量中,请执行var=$(command &lt;&lt;&lt; "$var")

【讨论】:

  • ${var##*_} 删除到最后一个
  • 是的!我只使用#,因为我知道它只是第一个重要的。但是,我正在编辑以表明这一点。谢谢
  • 如果您要创建一个综合列表,您也可以使用expr "$var" : "[^_]*_\(.*\)" :)
【解决方案2】:

或者,使用grep

echo fooo_barrrr | grep -oP '.*(?=_)'

要了解每个标志的含义,请使用grep --help

  • -P, --perl-regexp

    PATTERN 是一个 Perl 正则表达式

  • -o, --only-matching

    只显示匹配 PATTERN 的那部分行

为了避免两个以上的部分出现错误的结果,可以使用:

echo fooo_barrrr_xyz | grep -oP '.*?(?=_)' | head -1

【讨论】:

  • 请注意,echo fooo_barrrr_ca | grep -oP '.*(?=_)' 失败
  • 确实如此。我假设OP只有两个部分。已编辑。
  • 考虑到有一个内置的shell,这怎么算“高效”?
猜你喜欢
  • 2018-05-18
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多