【问题标题】:How to pass a variable line number in sed substitute command如何在 sed 替换命令中传递可变行号
【发布时间】:2019-07-12 13:26:56
【问题描述】:

我正在尝试像这样进行sed 操作

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

我想要一个变量中的 100,比如 perl 脚本中的 $var。所以,我正在尝试这样

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

这引发了一些错误。

当我这样做时,再次将系统命令放在单引号中:

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

这是错误的替换。可以做什么?

【问题讨论】:

  • 试试这个:system("sed -i $vars's/abc/xyz/' filename.txt").
  • @anubhava 我猜你的意思是system("sed -i '${vars}s/abc/xyz/' filename.txt")。更好更安全的是使用system(qw{sed -i}, "${vars}s/abc/xyz/", qw{filename.txt})
  • 一个建议。在 Perl 中很好地完成这项工作总共需要十几行代码,但我建议您这样做。这条“一条线”需要更多的复杂性,可能会出现故障和模糊的错误报告,可能取决于系统/版本,效率较低......我认为这不值得

标签: regex linux perl unix sed


【解决方案1】:

perl 内部向sed 发起攻击是通往不必要痛苦的道路。您正在引入额外的引用和变量扩展层,这充其量只会让您的代码不太清晰,最坏的情况是意外引入错误。

为什么不直接在原生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)

但我建议在您完成后“只是”重命名文件同样简单。

【讨论】:

    【解决方案2】:

    更好更安全的是使用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... 会更容易...

    【讨论】:

    • sed -i -e 作为单个参数看起来很奇怪,如果只是为了便于阅读,您不应该使用system(qw(sed), qw(-i), qw(-e), ...) 吗?
    • 好吧,恕我直言,最好是system('sed', '-i', '-e', ...)。但是引用是qw() 运算符的全部意义,不是吗?
    • 是的,但system(('sed', '-i', '-e'), ...) 中产生的额外括号是我所得到的。如果您将 qw(sed -i -e) 与以下参数合并到一个列表中,我对使用 qw(sed -i -e) 没有任何问题。
    • @tripleee 额外的括号是B::Deparse 的产物。所以实际上,当你使用qw() 时,你总是会得到这些,但因为你看不到它们,所以你不会打扰:-)
    猜你喜欢
    • 1970-01-01
    • 2023-01-02
    • 2021-02-01
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    • 2019-02-16
    • 2017-12-15
    • 2019-09-11
    相关资源
    最近更新 更多