Grep 查找文件中的特定模式并在第一个匹配项处停止
Grep for a specific pattern in a file and stop at the first match
我有一堆这样的 Nginx 虚拟主机文件:
# 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, "", file("{$host_dir}/{$matchs[0]}"));
echo "{$matchs[0]} => {$wp_domain[0]}";
}
}
我在 return 中得到了文件的第一行:
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 不是很熟悉,对此有点迷茫。 help/posts 的 None,可在网上找到,有效。基本上,类似这样的东西:sed -n -e 's|^.*server_name \(.*\);$||p' <file_name>
,我相信。
任何帮助将不胜感激。最好!
您可以使用
preg_match('~server_name\h*(.*);~', $s, $match);
echo $match[1];
看到这个regex demo
详情
server_name
- 文字子串
\h*
- 0+横白spaces
(.*)
- 第 1 组:除换行符以外的任何 0+ 个字符
;
- ;
.
实际上,我认为如果您添加 m 修饰符,您的方法将会奏效:
$_pattern = '/^.*server_name (.*);$/m';
*详情**:
^.*
- 一行的开头,然后是换行符以外的任何 0+ 个字符
server_name
- 文字子串
- space
(.*)
- 第 1 组:除换行符以外的任何 0+ 个字符
;
- ;
.
$
- 行尾
我有一堆这样的 Nginx 虚拟主机文件:
# 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, "", file("{$host_dir}/{$matchs[0]}"));
echo "{$matchs[0]} => {$wp_domain[0]}";
}
}
我在 return 中得到了文件的第一行:
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 不是很熟悉,对此有点迷茫。 help/posts 的 None,可在网上找到,有效。基本上,类似这样的东西:sed -n -e 's|^.*server_name \(.*\);$||p' <file_name>
,我相信。
任何帮助将不胜感激。最好!
您可以使用
preg_match('~server_name\h*(.*);~', $s, $match);
echo $match[1];
看到这个regex demo
详情
server_name
- 文字子串\h*
- 0+横白spaces(.*)
- 第 1 组:除换行符以外的任何 0+ 个字符;
-;
.
实际上,我认为如果您添加 m 修饰符,您的方法将会奏效:
$_pattern = '/^.*server_name (.*);$/m';
*详情**:
^.*
- 一行的开头,然后是换行符以外的任何 0+ 个字符server_name
- 文字子串(.*)
- 第 1 组:除换行符以外的任何 0+ 个字符;
-;
.$
- 行尾