Grep 查找文件中的特定模式并在第一个匹配项处停止

Posted

技术标签:

【中文标题】Grep 查找文件中的特定模式并在第一个匹配项处停止【英文标题】:Grep for a specific pattern in a file and stop at the first match 【发布时间】:2016-12-07 22:44:12 【问题描述】:

我有一堆这样的 nginx vhost 文件:

# This file was autogenerated by Puppet [ wordpress::vhost ]
# Any manual edit to this file will be automatically removed
# ©2016, DevOps team

server 
    listen 443 ssl;

    root /var/www/as888;
    index index.php;

    server_name wptraining-sdemo.mysysweb.com;
    ......
    ......

我需要从每个文件中提取 server_name 指令的值(即在这种情况下为 wptraining-sdemo.mysysweb.com)。我试过这个,使用preg_replace:

$host_dir = '/etc/nginx/sites-enabled';
$_pattern = '/^.*server_name (.*);$/U';

$_clients = scandir($host_dir);
foreach ( $_clients as &$client ) 
    if ( preg_match('/^as[0-9]3$/', $client, $matchs) ) 
        $wp_domain = preg_replace($_pattern, "$1", file("$host_dir/$matchs[0]"));
        echo "$matchs[0] => $wp_domain[0]";
    

我得到文件的第一行作为回报:

as888 => # This file was autogenerated by Puppet [ wordpress::vhost ]

如果我改用preg_grep

$wp_domain = preg_grep($_pattern, file("$host_dir/$matchs[0]"));
print_r($wp_domain);

我得到这样的东西:

Array
(
    [10] =>     server_name wptraining-sdemo.mysysweb.com;

)

这对我来说很奇怪,因为我期待[0](因为只有一场比赛)而不是[10]。看起来它正在为文件中的每一行创建一个数组。

我做错了什么?最重要的是,我错过了什么?我对 PHP 不是很熟悉,有点迷失其中。网上提供的帮助/帖子都没有工作。基本上,类似于此:sed -n -e 's|^.*server_name \(.*\);$|\1|p' <file_name>,我相信。 任何帮助将不胜感激。最好的!

【问题讨论】:

preg_grep 不会重置索引,它会返回原始数组中具有索引和值的确切项目。 preg_grep 只是一个测试,看看实际被 grepped 了什么。我的实际目标是提取server_name 和尾随; 之间的字符串。感谢您解决 preg_grep 之谜。 太好了,那你为什么不完全按照你的要求去做呢? preg_match('~server_name\h*(.*);~', $s, $match); echo $match[1];?实际上,如果您添加 m 修饰符,我认为您的方法将起作用:$_pattern = '/^.*server_name (.*);$/m'; - 请参阅 this demo。 看看this demo 我的 PHP 经验几乎是一天半的时间,所以还在赶上。刚刚发现mU 返回正确的值,如果我在脚本中指定$wp_domain[10],这对我来说是一个非常糟糕的脚本,因为我必须传递正确的行号,这可以改变任何时间。查看preg_match() 以了解它的实际作用。 【参考方案1】:

你可以使用

preg_match('~server_name\h*(.*);~', $s, $match); 
echo $match[1];

看到这个regex demo

详情

server_name - 文字子串 \h* - 0+ 个水平空格 (.*) - 第 1 组:除换行符以外的任何 0+ 个字符 ; - 一个;

实际上,我认为如果添加 m 修饰符,您的方法将起作用:

$_pattern = '/^.*server_name (.*);$/m';

见this demo

*详情**:

^.* - 一行的开头,然后是除换行符以外的任何 0+ 个字符 server_name - 文字子字符串 - 空格 (.*) - 第 1 组:除换行符以外的任何 0+ 个字符 ; - 一个;$ - 行尾

【讨论】:

以上是关于Grep 查找文件中的特定模式并在第一个匹配项处停止的主要内容,如果未能解决你的问题,请参考以下文章

Linux查找含有特定字符串的文件

[Linux 006]——grep和正则表达式

linux查找并输出特定行和它的前一行且在后面再输出一个空白行的命令

Linux基础6-1 grep和正则表达式

Linux基础6-1 grep和正则表达式

如何在 Go 中列出所有匹配的进程? [关闭]