如何在sed替代命令中传递可变行号

时间:2019-02-19 05:40:43

标签: regex linux perl unix sed

我正在尝试执行sed这样的操作

sed -i '100s/abc/xyz/' filename.txt

我想从perl脚本中的变量$ 100中输入100。因此,我正在尝试

system("sed -i "${vars}s/abc/xyz/" filename.txt"). 

这引发了一些错误。

再次像这样将系统命令放在单引号中

system('sed -i "${vars}s/abc/xyz/" filename.txt')

这是错误的替代。该怎么办?

2 个答案:

答案 0 :(得分:1)

更好和更安全的方法是使用system的LIST变体,因为它避免了不安全的Shell命令行解析。在您的情况下,命令sed将收到未更改且无需引用它们的命令行参数。

注意:我添加了-MO=Deparse只是为了说明单行编译的内容。

注意:我添加了-e才是安全的一面,因为您在命令行中有-i时需要一个参数。

 $ perl -MO=Deparse -e 'system(qw{sed -i -e}, "${vars}s/abc/xyz/", qw{filename.txt})'
 system(('sed', '-i', '-e'), "${vars}s/abc/xyz/", 'filename.txt');
 -e syntax OK

当然,实际上,仅在Perl中进行处理而不是调用sed ...

答案 1 :(得分:0)

sed内部扩展到perl是一条通往不必要痛苦的道路。您将引入额外的引号和变量扩展层,这充其量只能使您的代码不那么清楚,而最糟糕的是不小心引入了错误。

为什么不仅仅在本机perl中这样做,它更有效。如果需要,Perl甚至可以让您进行就地编辑。

但这很简单:

open ( my $input, '<', 'filename.txt'); 
open ( my $output, '>', 'filename.txt.new'); 

select $output; 
while ( <$input> ) {
   if ( $. == $vars ) { 
       s/abc/xyz/
   }
   print;
 }

或者如果您真的很喜欢就地编辑,则可以考虑设置`$ ^ I:

Perl in place editing within a script (rather than one liner)

但是我建议您在完成后“仅”重命名文件就很容易了。