【问题标题】:sed: How to extract only first occurance of valuesed:如何只提取第一次出现的值
【发布时间】:2017-07-26 00:19:19
【问题描述】:

我有文件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

问题是:我希望这个命令总是只返回一个值,所以我们说第一个。我可以在不将结果传递到第二个命令的情况下实现这一点吗?

【问题讨论】:

    标签: regex bash unix sed


    【解决方案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_,然后进入执行substitution 的块,prints 行,然后是quits

    【讨论】:

      【解决方案2】:

      也可以使用awk

      $ awk -F "'" '$2=="_DB_NAME_"{print $4; exit}' settings.inc.php 
      organic1
      
      • -F "'" 使用单引号作为输入字段分隔符
      • $2=="_DB_NAME_" 检查第二个字段是否为 _DB_NAME_
      • print $4如果条件满足,打印第四个字段
      • exit 因为只需要第一个匹配项

      【讨论】:

        【解决方案3】:

        将您的sed 命令传送到head 并选择第一行,如下所示:

        sed -rn 's/^.*_DB_NAME_'\'', '\''(\w+)'\''\);/\1/p' settings.inc.php | head -1
        

        【讨论】:

          【解决方案4】:

          如果您将替换命令后跟 print 转换为仅在模式(包含)_DB_NAME_ 寻址的行上运行的命令块,您可以在第一次匹配/打印后退出:

          $ sed -rn "/_DB_NAME_/ { s/.*'(\w+)'\);$/\1/p;q }" settings.inc.php
          organic1
          

          注意p 后面的q 命令。

          此外,您的 sed 脚本可以通过使用外部双引号并在末尾锚定来简化。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-05
            • 1970-01-01
            • 2011-02-07
            相关资源
            最近更新 更多