如何将$ SHELL变量传递给perl搜索并替换

How do I pass $SHELL variable into a perl search and replace

我有以下两个命令:

1
2
value=`grep -o Logs\/.*txt" textFILE`
perl -i -wpe's/" onclick="img=document\.getElementById\('\''img_1'\''\); img\.style\.display = \(img\.style\.display == '\''none'\'' \? '\''block'\'' : '\''none'\''\);return false"/$value/' textFILE

但是,我一直收到Use of uninitialized value $value in concatenation (.) or string at -e line 1, <> line 56.错误。 有人能告诉我我做错了什么。


有关以下示例:

1
2
$ value=$(uname -r)
$ perl -e 'print"$value"'

当我们运行Perl来执行我们的代码时,我们不会将shell变量$ value的内容发送给Perl。我们发送文字字符串'$ value',然后Perl将尝试打印不存在的Perl变量$ value。

您可以通过以下两种方式纠正此问题。

第一种方法是将您的Perl代码用双引号而不是单引号括起来,以便$ value在发送到Perl时成为shell变量$ value的内容而不是文字字符串'$ value':

1
2
3
$ value=$(uname -r)
$ perl -e"print '$value'"
3.13.9-generic

但是当你使用这个方法时,如果你有Perl变量和这个shell变量,你将需要'转义'Perl变量,否则你会得到如下错误:

1
2
3
$ value=$(uname -r)
$ perl -e"$example = 'test'; print "$value $example";"
syntax error at -e line 1, near"="

使用将更正此:

1
2
3
$ value=$(uname -r)
$ perl -e"\$example = 'test'; print "$value \$example";"
3.13.9-generic test

其次,您可以通过将"value"导出到环境中,然后通过Perl程序中已经可用的%ENV哈希访问它来避免将单引号更改为双引号(http://perldoc.perl.org/Env.html )。例如:

1
2
3
4
$ export value=$(uname -r)
$ perl -e 'print"$ENV{value}
"'

3.13.9-generic

请注意您的环境,不要意外覆盖某些所需的环境变量。使用对您的工作非常具体的命名约定可以帮助:

1
2
3
4
$ export MYPROGRAMNAME_KERNEL_VERSION=$(uname -r)
$ perl -e 'print"$ENV{MYPROGRAMNAME_KERNEL_VERSION}
"'

3.13.9-generic

大多数Linux系统上的printenv将显示当前建立的环境变量。您也可以使用Perl来检查%ENV。


把你之前的两个问题Why is my perl replace not working?How do I get a selection from the output of a grep放在一起,我将再次建议你在perl中完成所有这些。

以下脚本接受文件名作为参数并读取第一个值,然后在适当的位置编辑它以使用第一个值替换第二个值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use strict;
use warnings;

die"Usage: $0 Text_file
"
if @ARGV != 1;

my ($file) = @ARGV;

# Loop through file to find Value
my $value;
while (<>) {
    $value //= $1 if m{(Logs/.*?txt")};
}

die"
Unable to find value in $file
" if ! defined $value;

# Loop through file to edit
my $literal_string = q{ onclick="
img=document.getElementById('img_1'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false"};

local @ARGV = $file;
local $^I = '.bak';
while (<>) {
    s/\Q$literal_string/$value/;
    print;
}
#unlink"
$file$^I"; # Uncomment if you want to delete backup