Perl 不能转义带引号(“";”)的参数
我正在编写一个Perl脚本,它支持添加和修改特定文件中维护的参数。 脚本采用以下参数;参数名($paraName)、参数值($paraVal)和文件($profile)。 脚本检查参数($paraName)是否已经存在。如果是,它只更改值($paraVal),否则会将参数($paraName)和值($paraVal)添加到文件($profile)中 以下是相同的代码块:Perl 不能转义带引号(“";”)的参数,perl,scripting,Perl,Scripting,我正在编写一个Perl脚本,它支持添加和修改特定文件中维护的参数。 脚本采用以下参数;参数名($paraName)、参数值($paraVal)和文件($profile)。 脚本检查参数($paraName)是否已经存在。如果是,它只更改值($paraVal),否则会将参数($paraName)和值($paraVal)添加到文件($profile)中 以下是相同的代码块: print " checking if parameter is already avaialable"; my
print " checking if parameter is already avaialable";
my $response = system("egrep -qs \"$paraName =\" $profile");
$rc = 1;
if ($response == 0) {
print " Parameter is already available, changing the value now! ";
$rc = system("sed -i 's:.*$paraName.*:$paraName = $paraVal \# Parameter changed by $script:' $profile");
print " Parameter $paraName has been updated with the value $paraVal in the Profile successfully \n\n";
}
else{
print " Parameter is not available, Adding the Paremeter now! ";
$rc = system("echo \"$paraName = $paraVal \# Parameter added by $script\" >> $profile");
print " Parameter $paraName has been added with the value $paraVal in the Profile successfully \n\n";
}
该脚本在大多数情况下都可以正常工作,除非我将带有双引号的参数添加为新参数。当在一个引号(“”)内传递时,它可以用于散列(#)、斜杠()等文件
当参数($paraName)已经存在时,如果更改值($paraVal),则此操作有效。但是,虽然必须添加一个新参数,但这无法在参数名称中添加双引号
非常感谢您的帮助。下面是一个示例,说明如何将其编写为纯Perl:
use feature qw(say);
use strict;
use warnings;
my ( $paraName, $paraVal, $profile ) = @ARGV;
my $script = $0;
open ( my $fh, '<', $profile ) or die "Could not open file '$profile': $!";
my $found = 0;
while( my $line = <$fh> ) {
chomp $line;
if ( my ($key) = $line =~ /^(\Q$paraName\E)\s*=\s*/) {
say "$key = $paraVal \# Parameter changed by $script";
$found = 1;
}
else {
say $line;
}
}
close $fh;
if ( !$found ) {
say "$paraName = $paraVal \# Parameter added by $script";
}
使用功能qw(比如说);
严格使用;
使用警告;
我的($paraName,$paraVal,$profile)=@ARGV;
我的$script=$0;
打开(my$fh,“尝试以下代码作为替代
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Pod::Usage;
use Getopt::Long;
use Data::Dumper;
my %opt; # program options
my %param; # parameters storage
my $fh; # file handle
GetOptions (
'file|f=s' => \$opt{file},
'name|n=s' => \$opt{name},
'value|v=s' => \$opt{value},
'operation|o=s' => \$opt{op},
'help|h' => \$opt{help},
'man|m' => \$opt{man},
'debug|d' => \$opt{debug}
) or pod2usage(1);
pod2usage(1) if $opt{help};
pod2usage(-exitval => 0, -versose => 2) if $opt{man};
pod2usage(1) unless $opt{file};
open $fh, "< $opt{file}"
or die "Couldn't open $opt{file}";
my @lines = <$fh>;
close $fh;
chomp @lines;
print Dumper(\@lines) if $opt{debug};
push @lines, "$opt{name} = $opt{value}"
if $opt{op} eq 'add';
@lines = map { /$opt{name}\s*=/ ? '' : $_ } @lines
if $opt{op} eq 'del';
@lines = map {
s/($opt{name})\s*=\s*(.*)/$1 = $opt{value}/; $_
} @lines if $opt{op} eq 'mod';
map{ say } @lines
if $opt{op} eq 'view';
map {
/$opt{name}\s*=\s*(.*)/ and say 'Verify: '
. ($1 eq $opt{value} ? 'ok' : 'no')
} @lines if $opt{op} eq 'check';
my %save = map { $_ => 1 } qw/add del mod/;
print Dumper(\@lines) if $opt{debug};
if( $save{ $opt{op} } ) {
open $fh, "> $opt{file}"
or die "Couldn't open $opt{file}";
map { say $fh $_ } @lines;
close $fh;
}
__END__
=head1 NAME
program - modify configuration file
=head1 SYNOPSIS
program [options] [file ...]
Usage:
program -op [add|del|mod|view|check] -n param -v value -f file
Options:
--file,-f configuration filename
--name,-n parameter name
--value,-v parameter value
--operation,-o operation to perform
--help,-h brief help message
--man,-m full documentation
--debug,-d debug mode
=head1 OPTIONS
=over 8
=item B<--file,-f>
Configuration file to edit
=item B<--name,-n>
Configuration parameter name to operate on
=item B<--value,-v>
Configuration parameter value to operate on
=item B<--operation,-o>
Operation to perform on parameter: add, del, mod, view, check
=item B<--debug,-d>
Debug flag to print debug messages.
=item B<--help,-h>
Print a brief help message and exits.
=item B<--man,-m>
Prints the manual page and exits.
=back
=head1 DESCRIPTION
B<This program> allows to operate on configuation files variables.
=head1 AUTHOR
B<Polar Bear> L<https://stackoverflow.com/users/12313309/polar-bear>
=cut
!/usr/bin/perl
严格使用;
使用警告;
使用特征“说”;
使用Pod::用法;
使用Getopt::Long;
使用数据::转储程序;
我的%opt;#计划选项
我的%param;#参数存储
我的$fh;#文件句柄
获取选项(
'file | f=s'=>\$opt{file},
'name | n=s'=>\$opt{name},
'value | v=s'=>\$opt{value},
'操作| o=s'=>\$opt{op},
'help | h'=>\$opt{help},
'man | m'=>\$opt{man},
'debug | d'=>\$opt{debug}
)或POD2用法(1);
pod2usage(1)如果$opt{help};
如果$opt{man},则pod2usage(-exitval=>0,-versse=>2);
POD2用法(1),除非$opt{file};
打开$fh,“<$opt{file}”
或者死亡“无法打开$opt{file}”;
我的@lines=;
收盘价$fh;
咬线;
如果$opt{debug},则打印转储程序(\@行);
推送@lines,“$opt{name}=$opt{value}”
如果$opt{op}eq'add';
@lines=map{/$opt{name}\s*=/?'':$\u}@lines
如果$opt{op}eq'del';
@线条=地图{
s/($opt{name})\s*=\s*(.*)/$1=$opt{value}/$_
}@lines如果$opt{op}eq'mod';
映射{say}@行
如果$opt{op}eq‘view’;
地图{
/$opt{name}\s*=\s*(.*)/并说“验证:”
.($1 eq$opt{value}?'ok':'no')
}@lines如果$opt{op}eq‘check’;
我的%save=map{$\=>1}qw/adddelmod/;
如果$opt{debug},则打印转储程序(\@行);
如果($save{$opt{op}}){
打开$fh,“>$opt{file}”
或者死亡“无法打开$opt{file}”;
映射{say$fh$}@行;
收盘价$fh;
}
__结束__
=标题1名称
程序-修改配置文件
=总目1概要
程序[选项][文件…]
用法:
程序-op[add | del | mod | view | check]-n参数-v值-f文件
选项:
--文件,-f配置文件名
--名称,-n参数名称
--值,-v参数值
--操作,-o要执行的操作
--帮助,-h简短的帮助消息
--男,-m完整文档
--调试,-d调试模式
=标题1选项
=超过8
=项目B
要编辑的配置文件
=项目B
要操作的配置参数名称
=项目B
要操作的配置参数值
=项目B
对参数执行的操作:添加、删除、修改、查看、检查
=项目B
用于打印调试消息的调试标志。
=项目B
打印简短的帮助消息并退出。
=项目B
打印手册页面并退出。
=回来
=标题1说明
B允许对配置文件变量进行操作。
=第一作者
比尔
=切割
你能举一个$paraName
的例子吗?添加后,$profile
的预期内容是什么?还举一个如何调用脚本的例子你肯定有代码注入错误。为什么你甚至要用shell而不是用Perl来做?你可以用单引号来解决这个问题对于egrep
和echo
@HåkonHægland的第一个参数,$profile是将被编辑的文件的名称(它是非常特定于用例的,因此我省略了细节)。$paraName的一个例子是:“PA”“。我已经在使用单引号来容纳特殊字符。但如果让我们说,”,这就失败了。”“,仍将只向文件中写入内容。@ikegami,我不太确定是否理解。您是在说使用“echo”吗?如果您能纠正我并告诉我更好的方法,我将不胜感激,因为我对Perl非常陌生。感谢这个示例,出于某种原因,它没有附加到文件中。我认为您需要重定向的输出当前,它只是打印到标准输出(而不是修改文件)它需要修改文件本身。将添加该部分。谢谢。这样做,我只尝试了添加和修改选项。在我的解决方案中,我不希望用户担心提供添加或修改选项,如果参数已经存在,它只会更改它,否则会将其作为新参数添加。这也需要c有重复的参数。我会投票给你答案,但是我没有足够的声望点数。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Pod::Usage;
use Getopt::Long;
use Data::Dumper;
my %opt; # program options
my %param; # parameters storage
my $fh; # file handle
GetOptions (
'file|f=s' => \$opt{file},
'name|n=s' => \$opt{name},
'value|v=s' => \$opt{value},
'operation|o=s' => \$opt{op},
'help|h' => \$opt{help},
'man|m' => \$opt{man},
'debug|d' => \$opt{debug}
) or pod2usage(1);
pod2usage(1) if $opt{help};
pod2usage(-exitval => 0, -versose => 2) if $opt{man};
pod2usage(1) unless $opt{file};
open $fh, "< $opt{file}"
or die "Couldn't open $opt{file}";
my @lines = <$fh>;
close $fh;
chomp @lines;
print Dumper(\@lines) if $opt{debug};
push @lines, "$opt{name} = $opt{value}"
if $opt{op} eq 'add';
@lines = map { /$opt{name}\s*=/ ? '' : $_ } @lines
if $opt{op} eq 'del';
@lines = map {
s/($opt{name})\s*=\s*(.*)/$1 = $opt{value}/; $_
} @lines if $opt{op} eq 'mod';
map{ say } @lines
if $opt{op} eq 'view';
map {
/$opt{name}\s*=\s*(.*)/ and say 'Verify: '
. ($1 eq $opt{value} ? 'ok' : 'no')
} @lines if $opt{op} eq 'check';
my %save = map { $_ => 1 } qw/add del mod/;
print Dumper(\@lines) if $opt{debug};
if( $save{ $opt{op} } ) {
open $fh, "> $opt{file}"
or die "Couldn't open $opt{file}";
map { say $fh $_ } @lines;
close $fh;
}
__END__
=head1 NAME
program - modify configuration file
=head1 SYNOPSIS
program [options] [file ...]
Usage:
program -op [add|del|mod|view|check] -n param -v value -f file
Options:
--file,-f configuration filename
--name,-n parameter name
--value,-v parameter value
--operation,-o operation to perform
--help,-h brief help message
--man,-m full documentation
--debug,-d debug mode
=head1 OPTIONS
=over 8
=item B<--file,-f>
Configuration file to edit
=item B<--name,-n>
Configuration parameter name to operate on
=item B<--value,-v>
Configuration parameter value to operate on
=item B<--operation,-o>
Operation to perform on parameter: add, del, mod, view, check
=item B<--debug,-d>
Debug flag to print debug messages.
=item B<--help,-h>
Print a brief help message and exits.
=item B<--man,-m>
Prints the manual page and exits.
=back
=head1 DESCRIPTION
B<This program> allows to operate on configuation files variables.
=head1 AUTHOR
B<Polar Bear> L<https://stackoverflow.com/users/12313309/polar-bear>
=cut