我有一个像#!/bin/bash --args blah blah
这样的字符串,我想从中提取“bash”。
str="#\!/bin/bash --args blah blah"
echo "$str" | sed -r s/#\!.*?/(.*?)\>/\1/g
它给了我一个错误“bash:意外令牌附近的语法错误”('“。
我使用-r
启用了扩展正则表达式,不是吗?发生了什么事?
答案 0 :(得分:1)
你应该引用你的sed命令:
echo "$str" | sed -r "s/#\!.*?/(.*?)\>/\1/g"
在bash中,如果parens不在字符串文字中,则它们具有特殊含义
此外,您的sed命令会为sed: -e expression #1, char 18: unknown option to 's'
引发错误,因为您的模式中有一个未转义的/
。
答案 1 :(得分:1)
似乎您的字符串赋值错误,并且还使用不同的sed分隔符,因为输入包含正斜杠。
$ str='#!/bin/bash --args blah blah'
$ sed -r 's~#![^ ]*/([^ ]*)\b.*~\1~g' <<< $str
bash
答案 2 :(得分:0)
使用纯BASH内置插件:
str='#!/bin/bash --args blah blah'
[[ "$str" =~ \#\!/[^/]+/([^/ ]+) ]] && echo "${BASH_REMATCH[1]}"
bash
答案 3 :(得分:0)
Pure POSIX,没有bashisms,适用于任何 Bourne Shell:
$ str='#!/bin/bash --args blah blah'
$ shebang=${str%% *} # Remove space and all that follows
$ shell=${shebang##*/} # Remove up to and including /
$ echo $shell
bash
阅读shell手册中的“参数扩展”部分,了解有关这些内置字符串处理功能的更多信息。请注意,与使用shell内置功能相比,分配像sed
这样的外部程序在CPU周期方面非常昂贵。
答案 4 :(得分:0)
您也可以使用PCRE:
echo '#!/bin/bash --args blah blah' | grep -Po "(?<=/)[a-z]+(?= )"
这里正面的后视(?<=/)
确保/
在正则表达式之前,而正向前瞻(?= )
确保空格跟在正则表达式之后。因此,仅选择bash
作为输出。