我目前正在编写一个 Perl 脚本来解析配置文件。语法如下
{command parameter1 parameter2}
其中第二个参数是可选的。首先,我只想提取 {
和 }
之间的内容。我正在使用此代码
while (<FILE>) {
chomp;
unless ($_ =~ m/^\/\//) {
$_ =~ /^\{(.*?)\}/s;
print $1;
}
将进一步评估字符串,而不是 print
命令。我现在的问题是脚本停止处理某些字符串
只要参数两边有引号,脚本就可以工作。这个
{exec sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new}
将返回括号之间的内容,但由于可能有第二个参数,现在很难区分没有引号的参数
其他字符串,例如
{exec "cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak"}
{exec "/etc/init.d/ssh reload"}
工作完美,包括引号。
但是现在,引号中包含斜杠或加号(也许还有其他)的字符串此时会卡住 perl 脚本:
{exec "chmod +x /root/setSSHTimer.sh"}
{exec "sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new"}
两者都带有引号。当将第一个重写为“chmod 770...”时,它会再次起作用。
有什么想法导致这里出现问题吗?
最佳答案
问题不在于您所显示的代码,该代码只是提取 {...}
之间的所有内容大括号,但在进一步评估代码中。如果您遇到问题,请发布此内容
请注意,您只需使用不同的分隔符和类似 next if m|^//|
的行即可避免在正则表达式中转义斜杠。避免将循环的所有其余部分放在 if
中声明
解析命令行很尴尬 - 因为您必须处理 "..."
中包含的参数。和'...'
引号,允许在参数内使用转义引号 - 但可能
这是一个似乎可以正确解析所有示例数据的程序
use strict;
use warnings;
while (<DATA>) {
next if m|^//| or not /\S/;
if (/^\{(.*?)\}/) {
my $command = $1;
my @fields = $command =~ /'(?:\\'|[^'])*'|"(?:\\"|[^"])*"|\S+/g;
print join(' ', map "[$_]", @fields), "\n";
}
}
__DATA__
{exec sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new'}
{exec "cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak"}
{exec "/etc/init.d/ssh reload"}
{exec "chmod +x /root/setSSHTimer.sh"}
{exec "sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new"}
输出
[exec] [sed] ['s/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new']
[exec] ["cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak"]
[exec] ["/etc/init.d/ssh reload"]
[exec] ["chmod +x /root/setSSHTimer.sh"]
[exec] ["sed 's/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new"]
更新
此配置格式至少应按行分割,以便可以删除引号和转义符,例如
exec
sed
s/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/ /etc/ssh/sshd_config > /etc/ssh/sshd_config.new
exec
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
exec
/etc/init.d/ssh reload
exec
chmod +x /root/setSSHTimer.sh
exec
sed
s/ClientAliveInterval\ 300/ClientAliveInterval\ 1800/\' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new
正确输入和解析都很容易(尽管我确信你的最终 sed
示例是错误的!)
关于regex - Perl:匹配引号中包含斜杠的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12138508/