我正在编写一个shell脚本,它将运行一个命令并解析出最后几个数字(每次更改)。
运行npm run server
后要解析的文本,输出:
Please visit http;//mysite.com/id/2318
我想解析该值并将其分配给id
:
2318
我的尝试:
id=$(echo npm run server | sed -n 's:.*id\/\(.*\)\n.*:\1:p')
没有任何东西被退回。
答案 0 :(得分:2)
我的尝试:
id=$(echo npm run server | sed -n 's:.*id\/\(.*\)\n.*:\1:p')
没有 正在退货。
您可以尝试这样做:
id=$(npm run server | sed -E -e 's:(^.*)(id/)(.*$):\3:g')
注意:这解决了仅原始尝试的组件 显然 存在一些可行性问题。这并没有考虑任何因素,除了你应该从运行命令得到的引用输出字符串的前提。的即。我使用以下命令重现了这个:
echo 'Please visit http;//mysite.com/id/2318' | sed -E -e 's:(^.*)(id/)(.*$):\3:g'
因此,假设当您运行npm run server
时,您会得到输出'Please visit http;//mysite.com/id/2318'
(顺便说一下 - 我建议可能是http : //而不是http ; //),那么这个命令应该只返回id
组件。
如果您尝试过滤的文本是从stderr而不是stdout出来的,那么您实际上可能需要使用它:
id=$(npm run server &> >(sed -E -e 's:(^.*)(id/)(.*$):\3:g'))
例如,解析未配置的npm服务器的输出:
06:38:23 ✗ :~ >npm run server npm ERR! Darwin 15.5.0
06:38:23 ✗ :~ >npm run server | sed -E -e "s/(Darwin)/HELLO/g" npm ERR! Darwin 15.5.0
06:38:56 ✗ :~ >npm run server &> >(sed -E -e "s/(Darwin)/HELLO/g") npm ERR! HELLO 15.5.0
您可以在bash
手册中看到有关重定向stderr的信息:
Redirecting Standard Output and Standard Error
Bash allows both the standard output (file descriptor 1) and the stan- dard error output (file descriptor 2) to be redirected to the file whose name is the expansion of word with this construct. There are two formats for redirecting standard output and standard error: &>word and >&word Of the two forms, the first is preferred.
答案 1 :(得分:1)
我假设:
npm run server
作为命令调用。npm run server
在启动它的shell脚本退出后继续运行并不重要。如果所有这些假设都是正确的,请考虑为此工作替换流程:
#!/usr/bin/env bash
regex='Please visit .*/([[:digit:]]+)$' # define a regex to search for the string
exec 3< <(npm run server) # attach output from "npm run server" to FD 3
## the action is here: searching through output from server until we find a match
while read -r server_output <&3; do # loop reading a line at a time from the server
if [[ $server_output =~ $regex ]]; then # if a line matches the regex...
id=${BASH_REMATCH[1]} # then put the first capture group in a variable
break # and stop looping further.
fi
done
## after-the-fact: log success/failure, and set up any future output to be consumed
## ...so the server doesn't hang trying to write later output/logs to stdout w/ no readers.
if [[ $id ]]; then # if that variable contains a non-empty value
echo "Detected server instance $id" >&2 # log it...
cat </dev/fd/3 >/dev/fd/2 & cat_fd=$! # start a background process to copy any further
# stdout from service to stderr...
exec 3<&- # then close our own copy of the handle.
else
echo "Unable to find an id in stdout of 'npm run server'" >&2
exit 1
fi
## and we're done: if you like, run your other code here.
## also: if you want to wait until the server has exited
## (or at least closed its stdout), consider:
[[ $cat_fd ]] && wait "$cat_fd"