我有这个字符串
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 -i
grep
答案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