如何匹配,直到bash shell中最后一个字符出现

时间:2015-08-19 00:12:56

标签: regex bash shell grep

我在下面的输出中使用?- encode([a,a,a,a,b,c,c,a,a,d,e,e,e,e],Xs). Xs = [[4,a],[1,b],[2,c],[2,a],[1,d],[4,e]]. % succeeds deterministically curl

cut

Varible var=$(curl https://avc.com/actuator/info | tr '"' '\n' | grep - | head -n1 | cut -d'-' -f -1, -3) 有两种值(一次一种)。

var

我实际上是想把所有东西都拿到最后' - '。即HIX_MAIN-7ae526629f6939f717165c526dad3b7f0819d85b HIX-R1-1-3b5126629f67892110165c524gbc5d5g1808c9b5 HIX-MAIN

显示的命令可以正常运行HIX-R1-1

但是当我在变量中只有1 HIX-R1-1之类的东西时,我认为这是错误的做法;它为我提供了整个变量值(例如-)。

如何将变通HIX_MAIN-7ae526629f6939f717165c526dad3b7f0819d85b的最后一个' - '变为现实?

4 个答案:

答案 0 :(得分:13)

这将删除从上一个-到结尾的所有内容:

sed 's/\(.*\)-.*/\1/'

例如:

$ echo HIX_MAIN-7ae52 | sed 's/\(.*\)-.*/\1/'
HIX_MAIN
$ echo HIX-R1-1-3b5126629f67 | sed 's/\(.*\)-.*/\1/'
HIX-R1-1

如何运作

sed substitute命令的格式为s/old/new/,其中old是正则表达式。在这种情况下,正则表达式是\(.*\)-.*。这是有效的,因为\(.*\)-是贪婪的:它会匹配到最后-的所有内容。由于转发的问题\(...\),最后一个-之前的所有内容都将保存在第1组中,我们可以将其称为\1。最终.*匹配最后-之后的所有内容。因此,只要该行包含-,此正则表达式匹配整行,而替换命令将整行替换为\1

答案 1 :(得分:8)

您可以使用bash string manipulation

$ foo=a-b-c-def-ghi
$ echo "${foo%-*}"
a-b-c-def

运算符#%位于QWERTY键盘上$的任意一侧,有助于记住它们如何修改变量:

  • #pattern修剪最短的前缀匹配"模式"。
  • ##pattern修剪最长的前缀匹配"模式"。
  • %pattern修剪最短的后缀匹配"模式"。
  • %%pattern修剪最长的后缀匹配"模式"。

其中patternbash pattern matching rules匹配,包括?(一个字符)和*(零个或多个字符)。

在这里,我们正在修剪与模式-*匹配的最短后缀,因此${foo%-*}会为您提供所需的内容。

当然,有很多方法可以使用awksed执行此操作,可能会重复使用您已经运行的sed命令。但是,可变操作可以在bash中本地完成,而无需启动另一个进程。

答案 2 :(得分:3)

您可以在第二个字段中使用revcut,然后再次rev来反转字符串:

rev <<< "$VARIABLE" | cut -d"-" -f2- | rev

对于HIX-R1-1----3b5126629f67892110165c524gbc5d5g1808c9b5,打印:

HIX-R1-1---

答案 3 :(得分:2)

我认为你应该使用sed,至少在tr

之后
var=$(curl https://avc.com/actuator/info | tr '"' '\n' | sed -n '/-/{s/-[^-]*$//;p;q}')

-n表示默认不打印&#34;。 /-/查找包含短划线的行;然后执行s/-[^-]*$//删除最后一个破折号及其后的所有内容,然后p打印并q退出(因此它只打印第一个这样的行)。

我假设curl的输出本身包含多行,其中一些行中包含不需要的双引号,并且您只需匹配包含短划线的第一行(这很可能不是第一行)。一旦你将输入削减到唯一有趣的线,你可以使用纯shell技术来获得所需的结果,但获得唯一有趣的线并不像一些答案似乎微不足道假设。