用sed失败解析shebang

时间:2015-03-11 15:26:17

标签: regex linux bash sed

我有一个像#!/bin/bash --args blah blah这样的字符串,我想从中提取“bash”。

str="#\!/bin/bash --args blah blah"
echo "$str" | sed -r s/#\!.*?/(.*?)\>/\1/g

它给了我一个错误“bash:意外令牌附近的语法错误”('“。

我使用-r启用了扩展正则表达式,不是吗?发生了什么事?

5 个答案:

答案 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作为输出。