【问题标题】:how to extract the string from two delimiter strings using sed or awk or bash?如何使用 sed 或 awk 或 bash 从两个分隔符字符串中提取字符串?
【发布时间】:2019-04-30 22:06:13
【问题描述】:

我不经常使用 awk 或 sed。感谢您在以下方面的帮助:

我有一个带有值的 bash shell 变量 $VAR:

DEFINE QLOCAL ('IIB.TESTQUEUE.MODULE') +
DESCR('Input queue for A to B') +
LIKE('MY.LOCALQ.TEMP') +
REPLACE

我想提取值IIB.TESTQUEUE.MODULEQLOCAL<0 or more spaces>('') 之间来自 shell 变量 $VAR。

我根据其他现有问题和在线正则表达式工具构建了以下正则表达式,但是当我尝试将此正则表达式嵌入 awk 或 sed 时,这并没有打印任何内容。

【问题讨论】:

  • 我正在尝试排除单引号并稍作修改。$ echo $MQSCCMD | sed 's/.*QLOCAL*('\([^)]*\).*/\1/' bash: syntax error near unexpected token `)' ...看到转义单引号不起作用。
  • 你无法在 bash 单引号内转义 anything。它看到的第二个单引号终止了字符串。单引号不能出现在单引号字符串中。
  • grep -oP "your_pattern" file?我看到你在你的后视中有* 量化模式。我可以建议一个 PCRE 正则表达式与 GNU grep / pcregrep 一起使用吗?
  • 使用基本正则表达式sed "s/^.*QLOCAL[ ][(][']\([^']*\)['][)].*$/\1/" <<<$var
  • 尝试执行最简单的命令会得到各种奇怪/奇妙/不可能的结果,这意味着您没有告诉我们您是如何执行命令的。你说的是错误的事情,例如在your first comment above 中,该代码没有转义任何单引号,也没有告诉我们错误消息,因此我们必须查看实际的完整屏幕截图来帮助您。

标签: regex bash awk sed


【解决方案1】:

你的正则表达式的第一部分是可变宽度的正向向后看:

(?<=
  TOPIC \s*\('|
  QLOCAL\s*\('|
  QALIAS\s*\('|
  SUB   \s*\('
)

建议将文字单词合并到其自己的交替组中,并使用\K 运算符将匹配的文本从当前内存缓冲区中丢弃:(?:TOPIC|QLOCAL|QALIAS|SUB)\s*\('\K

其余部分可以与-oP 选项和GNU grep 一起使用:

grep -oP "(?:TOPIC|QLOCAL|QALIAS|SUB)\s*\('\K.*?(?='\))" file

查看regex demoonline grep demo

s="DEFINE QLOCAL ('IIB.TESTQUEUE.MODULE') +
DESCR('Input queue for A to B') +
LIKE('MY.LOCALQ.TEMP') +
REPLACE"
grep -oP "(?:TOPIC|QLOCAL|QALIAS|SUB)\s*\('\K.*?(?='\))" <<< "$s"
# => IIB.TESTQUEUE.MODULE

【讨论】:

  • res=$(echo $s | grep -oP "(?:TOPIC|QLOCAL|QALIAS|SUB)\s*('\K.*?(?='))") ,我正在尝试捕获此命令的结果,但这不起作用。请帮忙。
  • @learner echo $secho "$s" 不同。除非您有特定的需要,否则请始终引用您的变量。见mywiki.wooledge.org/Quotes
  • @EdMorton 表示感谢。请记住。正如你所说,我尝试使用“$s”。我仍然没有在变量 s 中看到任何值。当我 echo s 时,我看到我的输入是通过管道传输到 grep 的,当我运行整个命令时,我看到了结果,但它没有存储在变量 res 中。
  • @learner 不知道为什么它不适合你work
【解决方案2】:

记住匹配的字符串:

echo "${VAR}" | sed -n "s/.*QLOCAL *('\([^']*\)').*/\1/p"

题外话:shell 变量使用小写。

编辑:正如@EdMorton 所说,删除了空间周围的[]

【讨论】:

  • @learner 上面的内容可以与任何 UNIX 机器上任何 shell 中的任何 sed 一起稳健地工作,因此您可能希望专注于使用此解决方案进行测试,以消除除试验错误之外的任何可能的故障来源。
  • 是的。这工作没有任何问题。我试图使用 $() 将结果捕获到 shell 变量中,但我没有看到结果变量中的值。不确定这是行不通的。
  • 你试过newvar=$(echo "${VAR}" | sed -n "s/.*QLOCAL *('\([^']*\)').*/\1/p")=周围没有空格吗?
【解决方案3】:
$ echo "$var" | grep -oP "QLOCAL *\('\K[^']+"

IIB.TESTQUEUE.MODULE

不确定,为什么你的作业有问题

$ val=$(echo "$var" | grep -oP "QLOCAL *\('\K[^']+")
$ echo "$val"
IIB.TESTQUEUE.MODULE

【讨论】:

  • 我正在尝试捕获此命令的结果,如下所示。 res=$(echo "${mqsc_cmd}" | sed -n "s/.*QLOCAL *('([^']*)').*/\1/p") ,但 $res 为空。可以这样拍吗?
  • @learner 当然,但您在 grep 答案下询问 sed 解决方案。如果您对某人在答案中发布的脚本有疑问,请在 that 答案下的评论中提问,而不是在其他答案下。
  • 我的错。我测试了上面和这个答案。我把我的测试贴错了。
  • 当我运行上述命令时,我得到了响应,但是当我将上述命令放在 S=$() 中时,它不会将结果存储在 S 中。我尝试将其放在单引号中但它会抛出错误。
  • 将其放在单引号中不会产生您想要的输出,但不会引发错误。
【解决方案4】:

使用简单的剪切命令: echo $VAR|cut -d' -f2

【讨论】:

  • 是的,我测试过了。它没有给出任何结果。
  • @learner 如果它没有给出 any 结果,那么问题就出在您身上(例如,您提供的示例输入看起来不像您是真正的输入,或者您复制/粘贴此代码错误).. 鉴于您提供的示例输入,此代码将产生一些输出,而不是您要求的输出。
  • 实际上我已经纠正了,它会产生你想要的输出,因为它没有引用 $VAR ,这是不可取的,因为它有潜在的副作用,但在这种情况下,除非你对 globbing、输入值不走运,等等它可能会产生您要求的输出(但仍然不要这样做,因为这是错误的方法)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多