Regex 这些Perl一行程序中的每一个都发生了什么?

Regex 这些Perl一行程序中的每一个都发生了什么?,regex,perl,command-line-interface,Regex,Perl,Command Line Interface,我试图理解cli中的perl one行程序。 例如,如果我需要在文件中进行替换,如果我这样做: perl -e 's/eat/read/g' file 什么也没发生 如果我这样做: perl -i -e 's/eat/read/g' file 文件也没有发生任何变化 除非我这样做: perl -p -i -e 's/eat/read/g' file 文件中的内联替换发生。 如果我这样做 文件变为空 有人能解释一下它们之间的区别以及每种情况下会发生什么吗?摘自perl-h: Usage:

我试图理解cli中的perl one行程序。
例如,如果我需要在文件中进行替换,如果我这样做:

perl -e 's/eat/read/g' file  
什么也没发生

如果我这样做:

perl -i -e 's/eat/read/g' file
文件也没有发生任何变化

除非我这样做:

perl -p -i -e 's/eat/read/g' file
文件中的内联替换发生。
如果我这样做

文件变为空


有人能解释一下它们之间的区别以及每种情况下会发生什么吗?

摘自
perl-h

Usage: perl [switches] [--] [programfile] [arguments]
  -e program        one line of program (several -e's allowed, omit programfile)
  -i[extension]     edit <> files in place (makes backup if extension supplied)
  -n                assume "while (<>) { ... }" loop around program
  -p                assume loop like -n but print line also, like sed
它将按预期修改您的文件,并使用后缀
保存备份。bak

模块将显示开关对您的perl代码所做的操作

perl -MO=Deparse -e 's/eat/read/g' file
s/eat/read/g;
这里没有什么有趣的,您的代码按原样执行

perl -MO=Deparse -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
s/eat/read/g;
好的,
-i
更改了用于内联编辑的全局变量,但没有读取任何文件,这里也没有循环

perl -MO=Deparse -p -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/eat/read/g;
}
continue {
    print $_;
}

因此,
-n
没有像
-p
开关一样打印的
继续{}
块,如果您想对文件进行所需的更改,您必须在
s///
替换后手动打印(否则将不打印任何内容,并且您的文件将被截断,正如您已经注意到的那样).

我建议您阅读这篇文章:告诉您每一个都做什么。第一个不做任何事情,因为没有设置任何标志来调用将文件馈送到脚本的行为。第二个出于同样的原因什么也不做。第三种方法之所以有效,是因为您告诉Perl遍历一个文件并将输出作为就地编辑发送到该文件。。。您已经告诉Perl,您总是希望为每行输出$。第四个失败是因为,尽管您正在迭代该文件并进行就地编辑,但您从未向该文件发送任何输出,因此该文件变为空printed@Jim-给定内容为abc的
文件
perl-p-e的s/a/X/”文件
打印
Xbc
。仔细检查您的文件和命令行。
perl -MO=Deparse -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
s/eat/read/g;
perl -MO=Deparse -p -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/eat/read/g;
}
continue {
    print $_;
}
perl -MO=Deparse -n -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/eat/read/g;
}