Perl 不能转义带引号(“";”)的参数

Perl 不能转义带引号(“";”)的参数,perl,scripting,Perl,Scripting,我正在编写一个Perl脚本,它支持添加和修改特定文件中维护的参数。 脚本采用以下参数;参数名($paraName)、参数值($paraVal)和文件($profile)。 脚本检查参数($paraName)是否已经存在。如果是,它只更改值($paraVal),否则会将参数($paraName)和值($paraVal)添加到文件($profile)中 以下是相同的代码块: print " checking if parameter is already avaialable"; my

我正在编写一个Perl脚本,它支持添加和修改特定文件中维护的参数。 脚本采用以下参数;参数名($paraName)、参数值($paraVal)和文件($profile)。 脚本检查参数($paraName)是否已经存在。如果是,它只更改值($paraVal),否则会将参数($paraName)和值($paraVal)添加到文件($profile)中

以下是相同的代码块:

   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