我正在编写一个bash脚本,需要让npm run server
完成运行,这将输出我需要的ID号
npm run server
输出
running server...
....
...
...
Server version is /id/1345
我需要在命令完成运行后解析1345
。
我尝试过以下但没有成功:
idd=$(npm run server "$domain" &> >(sed -E -e 's:(^.*)(id/)(.*$):\3:g'))
echo $idd
抛出:
run.sh: command substitution: line 27: syntax error near unexpected token `>'
我也尝试过:
bundle_counter=$(npm run server "$domain" | sed -E -e 's:(^.*)(/b/)(.*$):\3:g')
失败了。
答案 0 :(得分:2)
idd=$(npm run server "$domain" | sed -n -E '$s+id/(.*)$+\1+p')
我将npm的输出输出到sed,就像你在第二个片段中所做的那样。您也使用的-E
标志可以启用扩展的正则表达式。我现在甚至不需要这些,但我认为它是标准的,因为ERE更有用。
-n
告诉sed默认情况下不会在转到下一行时打印其缓冲区。它与在所有其他命令之后在每个输入行上使用d
时大致相同。使用-n
时,您必须明确要求sed使用p
命令打印某些行 - 但这实际上并未在此处使用,因为我们很快就会看到!
$
将确保该命令仅在输入的最后一行执行。
s
命令是替换命令。你可以在它之后使用任何字符,这将是s
的分隔符。经典是/
,但在这里我使用+
,因为我们在针中使用/
,这样我们就不必逃避{{1} }}。 /
是针,id/(.*)$
是替代品。你没有必要像你一样锚定你的字符串,所以\1
和相应的替换^(.*)id/(.*)$
的针是等价的但是多余的(并且很可能会产生轻微的性能开销)。
因为在\2
之后没有分号,s
实际上不是这里的单独命令,而是p
的标志。如果s
命令成功找到要替换的内容,它将打印缓冲区。
答案 1 :(得分:2)
idd=$(npm run server "$domain" 2>&1 | sed -E -ne 's:(^.*)(id/)(.*$):\3:p')
2>&1
将stderr合并到stdout。-n
不打印任何不匹配的行。p
打印匹配。答案 2 :(得分:1)
错误消息表明您正在调用Bash为sh
(或至少在POSIX兼容模式下),在这种情况下进程替换({{ 1}}和<(...)
)不受支持,因为他们不属于POSIX 。
如果您的>(...)
命令原则上有效,那么确保您的命令由sed
运行 - 通过该名称调用 就足够了,使用shebang line bash
。
也就是说,使用输出过程替换是不必要的复杂。
#!/bin/bash
命令的问题:您的sed
命令无法按预期工作,因为在没有选项sed
的情况下,-n
仍会打印所有(可能已修改) )输入线,而不仅仅是(修改过的)感兴趣的线
因此,sed
(替换)命令的正则表达式与匹配的任何行仍然是仍然打印,按原样。
有关可行的解决方案,请参阅Ewan Mellor's helpful answer。