sed 不贪婪地匹配通配符来裁剪字符串部分

sed 不贪婪地匹配通配符来裁剪字符串部分

我有这个字符串

extension_dir => /some/path/php/extensions/no-debug-non-zts-20160303 => /some/path/php/extensions/no-debug-non-zts-20160303
sqlite3.extension_dir => no value => no value

这是 的输出php -i | grep extension_dir

我如何在 bash 中解析它以获得第一个/some/path/php/extensions/no-debug-non-zts-20160303

到目前为止我已经尝试过:

echo $(php -i | grep extension_dir | sed 's/extension_dir => //g' | sed 's/=> .*//g')

但这给了我/some/path/php/extensions/no-debug-non-zts-20160303 sqlite3.no value。我不知道为什么它不取代所有匹配=> .*

我的基本想法是首先摆脱extension_dir =>,然后再摆脱所有内容=>,包括=>可能 sed 匹配的内容与正则表达式不同。

答案1

php -i | sed -n '/extension_dir/{s/^[^/]*//;s/ *=>.*$//;p;}'

或者,正如下面评论中所建议的,

php -i | sed '/extension_dir/!d;s/[^/]*//;s/ *=>.*//'

上面的内容sed替换了 yourgrep和 will,对于匹配的每一行extensions_dir,首先删除第一行之前的所有内容/,然后删除从第一行=>开始的所有内容修改的细绳。之前的所有空格=>也将被删除。不匹配的行将extensions_dir被忽略。

这将为第一行输入返回所需的路径,并为第二行返回空行。

要忽略第二行输入,请在上面使用/^extension_dir/而不是。这将丢弃第二行,因为它不以该字符串开头。/extension_dir/sed


这是两个脚本的组合sed,为第二行输入产生了令人惊讶的结果。

该行是

sqlite3.extension_dir => no value => no value

第一个sed会将其修改为

sqlite3.no value => no value

然后第二个sed将删除=> no value末尾的位。


注意

echo $( ... )

有点没用,因为它会吞噬内部命令输出中的换行符$( ... )。相反,仅使用命令进行测试,而不使用echo$( ... )命令替换。

可能正是这种用法让您对and 的echo输出性质感到困惑(两条匹配行而不是一条)。php -igrep

答案2

我可以给你一个简单的 awk 解决方案。

php -i | awk -F ' => ' '/extension_dir/{print $2; exit}'

如果你想丢失 sed,这会起作用。

编辑:将 exit 移至块内部以避免语法错误,在字段分隔符周围添加空格,以便它们不会与结果文件路径一起输出,并描述正文中的更改,因此 stackexchange 允许由于最小字符更改限制而进行编辑。

答案3

如果路径不包含空格,则此表达式就足够了:

php -i | grep -Po 'extension_dir => \K/[^ ]*'

输入

extension_dir => /some/path/php/extensions/no-debug-non-zts-20160303 => /some/path/php/extensions/no-debug-non-zts-20160303
sqlite3.extension_dir => no value => no value

输出

/some/path/php/extensions/no-debug-non-zts-20160303

相关内容