我非常擅长使用 php 的preg_match
(和类似的)命令,而且我也非常擅长使用正则表达式,但是我不太擅长使用sed
.
我正在处理两个 shell 脚本,我希望能够从配置文件中提取一些变量。
第一个文件
第一个文件是一个.htaccess
文件,我想获取网址,该网址将位于如下所示的块中:
RewriteCond %{HTTP_HOST} !^www\.mysite\.net$
RewriteRule (.*) http://www.mysite.net/$1 [R=301,L]
该文件的语法.htaccess
将非常规则,因此我觉得我应该使用类似于#.*(http.*?)\$#is
以下内容的模式:
- 正则表达式
- 由 # 分隔
- http 之前有 0 个或多个字符
- 使用非贪婪符号在 http 上开始捕获?
- 继续捕获,直到遇到实际的美元符号(转义)
- 匹配不区分大小写
- 忽略空格/换行符
如何将正则表达式与类似命令一起使用sed
,以便在匹配时获得括号内的部分,如果不匹配则获得任何内容(空字符串)?
sed
除了我习惯了 php 的 PCRE之外,我使用另一个命令会更好吗?
第二个文件
第二个文件有点不同,因为它是一个.ini
文件,所以我想知道是否可能有一些 shell 魔法(我使用bash
)来解析它。我想要的块看起来像这样:
[Database]
database = mysql://user:password@localhost/database
如果我使用 PHP 和正则表达式,我会这样做:
#\s+database\s*=\s*mysql://([\:]+):([\@]+)@([\/]+)/(.*?)\s+#is
在 PHP 中,有一个 .ini 解析器,但我希望这是一个 shell/bash 脚本,而不是 PHP 脚本
如何使用该正则表达式来获取数据库连接凭据?
答案1
如果您想使用类似 perl 的正则表达式,为什么不使用 perl(99% 的非嵌入式 Unices 上都可以找到它)?
喜欢:
perl -lne 'print for /(http.*?)\$/'
perl -lne 'print for m{database\s*=\s*mysql://([^:@]+):([^@]+)@([^/]+)/(\S+)}i'
/.../
是 的缩写形式m/.../
。允许m/.../
除 之外的其他字符/
,也允许像m{...}
,这样的字符对m(...)
。
something for @list
something
作为$_
列表值上的变量运行循环。m{...}
在列表上下文中返回捕获模式的列表(内部(...)
)。print
不带参数,打印$_
.
答案2
尝试
grep -oP <your_pattern> <your_file>
确保-P
将grep
您的正则表达式解释为 Perl 并-o
使其仅返回匹配的内容。
编辑:请注意,您grep
可能不一定支持惰性量词,因此,如果您不希望 URL 运行多行,我会使用不带/s
修饰符的贪婪量词。