我不是 bash 专家,在过滤出正确的子字符串方面遇到了麻烦。
我有
echo "AT^SYSCFGEX=\\\"0201\\\",3fffffff,2,4,7fffffffffffffff,,"
结果是
AT^SYSCFGEX=\"0201\",3fffffff,2,4,7fffffffffffffff,,
我怎样才能得到0201
结果?我正为此苦苦挣扎。
答案1
和sed
sed -r 's/[^0-9]*([0-9]+).*/\1/'
从字符串中提取第一个数字。
示例运行
$ echo "AT^SYSCFGEX=\\\"0201\\\",3fffffff,2,4,7fffffffffffffff,," | sed -r 's/[^0-9]*([0-9]+).*/\1/'
0201
解释
-r
– 使用扩展正则表达式s/a/b/
–a
替代b
[^0-9]*
– 抓取除数字之外的所有内容,这里匹配AT^SYSCFGEX=\"
([0-9]+)
– 抓取至少一个数字并将其保存在一个组中,这里匹配0201
.*
– 抓取整行的剩余部分,这里匹配\",3fffffff,2,4,7fffffffffffffff,,
\1
– 获取之前保存的第一组内容
答案2
grep
以下是在 PCRE 模式 ( ) 中使用正则表达式查找的替代方法-P
,仅显示每行的匹配部分 ( -o
):
grep -Po '(?<=\\")\d+(?=\\")'
这将匹配所有用反斜杠转义的双引号括起来的数字,如\"0201\"
,但不返回结果中的引号。
(?<=\\")
是一个后视,如果它前面有内部模式(\"
),则它匹配一个空字符串。\d+
匹配一个或多个数字。(?=\\")
是前瞻指令,如果它后面跟着内部模式 (\"
),它会匹配一个空字符串。
例子:
$ echo "AT^SYSCFGEX=\\\"0201\\\",3fffffff,2,4,7fffffffffffffff,," | grep -Po '(?<=\\")\d+(?=\\")'
0201
答案3
和bash
的参数扩展
如果您只想使用,bash
您可以这样做:
$ var="AT^SYSCFGEX=\\\"0201\\\",3fffffff,2,4,7fffffffffffffff,,"
$ echo ${var#*\"}
0201\",3fffffff,2,4,7fffffffffffffff,,
$ var=${var#*\"}
$ echo ${var%%\\\"*}
0201
解释
${var#*\"}
– 扩展到变量的内容,并从开头剥离var
模式匹配*"
(即直到的所有内容)"
${var%%\\\"*}
– 扩展为变量的内容,并从末尾剥离var
模式匹配\"*
(即来自的所有内容)。\"
进一步阅读
答案4
这是一种awk
方法。这里的想法是awk
(或者准确地说,GNU awk
)可以使用多个字符作为分隔符。因此,我们可以使用\
和"
作为分隔符,使用以下命令提取所需的字符串:
awk -F '[\\\\"]' '{print $3}'
请注意多个\
,它们对于转义反斜杠是必需的,并避免它被 shell 解释为下一个字符的转义。
使用echo
问题中的命令,
$ echo "AT^SYSCFGEX=\\\"0201\\\",3fffffff,2,4,7fffffffffffffff,," | awk -F '[\\\\"]' '{print $3}'
0201
或者,我们可以只使用"
作为分隔符并切断最后的\
viasubstr()
函数:
$ echo "AT^SYSCFGEX=\\\"0201\\\",3fffffff,2,4,7fffffffffffffff,," | awk -F '"' '{print substr($2,1,length($2)-1)}'
0201