我的文件settings.inc.php
包含以下内容:
<?php
define('_DB_SERVER_', 'mariadb');
define('_DB_NAME_', 'organic');
define('_DB_USER_', 'prestashop');
define('_DB_PASSWD_', 'prestashop');
我想将这些值提取到bash
,因此我设法创建了以下命令:
sed -rn 's/^.*_DB_NAME_'\'', '\''(\w+)'\''\);/\1/p' settings.inc.php
这将返回organic
,就像它应该的那样,但我想进一步改进它。让我们说我们会有这样的文件:
<?php
define('_DB_SERVER_', 'mariadb');
define('_DB_NAME_', 'organic1');
define('_DB_NAME_', 'organic2');
define('_DB_USER_', 'prestashop');
define('_DB_PASSWD_', 'prestashop');
在这个文件上使用上面的命令,我们得到:
organic1
organic2
问题是:我希望此命令始终只返回一个值,所以让我们说第一个。如果没有将结果输入第二个命令,我能实现吗?
答案 0 :(得分:2)
也可以使用awk
$ awk -F "'" '$2=="_DB_NAME_"{print $4; exit}' settings.inc.php
organic1
-F "'"
使用单引号作为输入字段分隔符$2=="_DB_NAME_"
检查第二个字段是否为_DB_NAME_
print $4
如果条件满足,请打印第4个字段exit
因为只需要第一场比赛答案 1 :(得分:1)
使用GNU grep,你可以做到:
grep -m1 -Po "_DB_NAME_', '\K[^']+" settings.inc.php
grep参数是:
-m 1
:在1场比赛后停止搜索-P
:打开Perl样式正则表达式(所以我们可以在这里使用\K
)-o
:仅打印与模式匹配的部分模式的\K
部分表示不包括作为匹配的一部分的所有内容,然后我们让模式的其余部分找到不是'
的所有内容。
如果您想坚持sed
,可以找到_DB_NAME_
行,然后在找到后退出:
sed -rn '/_DB_NAME/ {s/^.*_DB_NAME_'\'', '\''(\w+)'\''\);/\1/;p;q}' settings.inc.php
匹配_DB_NAME_
,然后进入您的s
ubstitution,p
划线,然后q
uits
答案 2 :(得分:0)
如果将替换命令后跟print打印到仅在pattern(包含)_DB_NAME_
寻址的行上操作的命令块,则可以在第一次匹配/打印后退出:
$ sed -rn "/_DB_NAME_/ { s/.*'(\w+)'\);$/\1/p;q }" settings.inc.php
organic1
请注意q
之后的p
命令。
此外,您可以通过使用外部双引号并在末尾锚定来简化您的sed
脚本。
答案 3 :(得分:0)
将sed
命令发送到head
并选择第一行,如下所示:
sed -rn 's/^.*_DB_NAME_'\'', '\''(\w+)'\''\);/\1/p' settings.inc.php | head -1