当前位置: 首页 > 面试题库 >

sed命令在命令行上运行,但不在perl脚本中

穆智刚
2023-03-14
问题内容

我有一个文件,其中我必须替换所有单词,如$ xyz,对于它们,我必须替换为以下内容:

$xyz with ${xyz}.
$abc_xbs with ${abc_xbc}
$ab,$cd  with ${ab},${cd}

这个文件也有一些像$ {abcd}这样的词,我不必更改。我正在使用此命令

sed -i’s?\ $([A-Z _] +)?\ $ {\ 1}?g’文件

它可以在命令行上正常工作,但不能在perl脚本中作为

sed -i 's?\$\([A-Z_]\+\)?\$\{\1\}?g' file;

我想念什么?我认为添加一些反斜杠会有所帮助。我尝试添加一些但没有成功。

谢谢


问题答案:

在Perl脚本中,您需要有效的Perl语言,就像在C程序中需要有效的C文本一样。在终端sed..中,shell是作为命令来理解和运行的,但是在Perl程序中,它只是一堆单词,而该行sed..不是有效的Perl。

您可能需要在内部qx()(反引号)或system()使其作为外部命令运行。然后,您确实需要“ 一些反斜杠 ”,这会使事情变得有些挑剔。

但是,为什么sed要从Perl脚本运行命令?用Perl完成工作

use warnings;
use strict;
use File::Copy 'move';

my $file     = 'filename';
my $out_file = 'new_' . $file;

open my $fh,     '<', $file     or die "Can't open $file: $!";
open my $fh_out, '>', $out_file or die "Can't open $out_file: $!";

while (<$fh>) 
{
    s/\$( [^{] [a-z_]* )/\${$1}/gix;
    print $fh_out $_;
}
close $fh_out;
close $fh;

move $out_file, $file or die "Can't move $out_file to $file: $!";

正则表达式使用一个 否定的字符类
[^...]以匹配比以外的任何字符{之后$,因此排除了已掺进字。然后,它与字母或下划线序列相匹配,如在问题中一样(可能没有,因为第一个非字母{已经提供了至少一个)。

在5.14+中,您可以使用 非破坏性 /r
修饰符

print $fh_out s/\$([^{][a-z_]*)/\${$1}/gir;

用来返回更改后的字符串(并且原始字符串不变)的右侧print

最后,应使用File ::Temp制作输出文件,并移至原始文件上方。以此方式覆盖原始文件将更改$fileinode的编号;

单行(命令行)版本,易于测试

perl -wpe's/\$([^{][a-z_]*)/\${$1}/gi' file

这仅打印到控制台。更改原始添加-i(就地)或-i.bak保留备份。

出现了一个合理的问题“ 没有更短的方法了 ”。

这是一个使用方便的Path :: Tiny的文件,它不大,因此我们可以将其读取为字符串。

use warnings;
use strict; 
use Path::Tiny;

my $file     = 'filename';
my $out_file = 'new_' . $file;

my $new_content = path($file)->slurp =~ s/\$([^{][a-z_]*)/\${$1}/gir;

path($file)->spew( $new_content );

第一行将文件读入一个字符串,在该字符串上进行替换;更改后的文本将返回并分配给变量。然后,带有新文本的变量将覆盖原始变量。

通过将表达式从第一行而不是变量放在第二行,可以将这两行压缩为一个。但是,在一个(复杂)语句中两次打开同一文件并不是完全可靠的做法,因此我不建议您使用这种代码。

但是,由于模块的版本为0.077,您可以很好地执行

path($file)->edit_lines( sub { s/\$([^{][a-z_]*)/\${$1}/gi } );

或使用edit将文件插入字符串并对其应用回调。

因此,这毕竟将其切成一条漂亮的线。

我想补充一点,删节代码行几乎是不值得的,但是如果它干扰了对代码结构和正确性的关注,那肯定会导致麻烦。但是,这Path::Tiny是一个很好的模块,这是合法的,尽管它确实使事情大大缩短了。



 类似资料:
  • 问题内容: 当我尝试从PyCharm IDE运行程序时,一切正常,但是如果我输入Fedora: 在shell提示中,我从1个模块收到导入错误。 当从IDE启动时,PyCharm可以执行哪些操作以使解释器找到我的依赖项?如何获得脚本以找到其依赖项,以便可以使用singe命令启动它? 问题答案: 有一些可能的原因可能导致这种情况: 相同的python解释器?检查与 它是同一工作目录吗?检查与 中的差异

  • 我如何通过命令行运行它?

  • 我得到 它不包含我在NetBeans中使用的jdk的路径。我没有找到一种方法告诉Java我想使用另一个jdk,所以我尝试了不使用: 运行特定主文件的示例 在java.lang.class.PrivateGetMethodRecursive(class.java:3048) 在java.lang.class.GetMethod0(class.java:3018) 在java.lang.class.G

  • 问题内容: 我试图从Java 运行命令而没有成功。这是我的Java代码: 我也尝试过: 问题是,如果我打印出的内容并在终端中运行它,它将起作用。由于某种原因,它只是不从Java执行。更清楚地说,当我直接从终端运行命令时,“ items.xml”文件就会更改。当我从Java运行它时,文件不会更改。我已验证该命令正确无误,如下所示。 我想念什么吗? cmd的输出是 **编辑 我根据以下评论进行了以下更

  • 问题内容: 我有一个具有某些功能的脚本。 我可以直接从命令行运行功能之一吗? 像这样吗 问题答案: 如果脚本仅定义函数,而不执行其他任何操作,则可以先使用or 命令在当前shell的上下文中执行脚本,然后简单地调用函数。请参阅以获取更多信息。

  • 问题内容: 我在Node中编写一个Web应用程序。如果我有一些带有函数的JS文件,如何从命令行调用该函数? 问题答案: 对于您为什么要这样做,或者什么是更标准的做法,没有任何评论:这是您问题的解决方案…。请记住,命令行所需的引号类型可能会有所不同。 在您中,导出功能。有很多方法,但是例如: 然后假设您与命令提示符在同一目录中,然后这样调用它: 对于其他读者来说,OP的 功能可以被称为任何东西,这并