Perl单行中的每一个都会发生什么?

Jim*_*Jim 2 regex perl command-line-interface

我试图理解cli中的perl一个衬里​​.
例如,如果我需要在文件中进行替换:

perl -e 's/eat/read/g' file  
Run Code Online (Sandbox Code Playgroud)

什么都没发生.

如果我做:

perl -i -e 's/eat/read/g' file
Run Code Online (Sandbox Code Playgroud)

文件也没有任何反应.

只有我这样做:

perl -p -i -e 's/eat/read/g' file
Run Code Online (Sandbox Code Playgroud)

文件中的替换内联发生了.
如果我做

perl -n -i -e 's/eat/read/g' file
Run Code Online (Sandbox Code Playgroud)

文件变空了!

有人可以解释一下这些差异以及每种情况会发生什么吗?

Сух*_*й27 8

B :: Deparse模块将显示你的perl代码所做的切换,

perl -MO=Deparse -e 's/eat/read/g' file
s/eat/read/g;
Run Code Online (Sandbox Code Playgroud)

没有什么有趣的,你的代码按原样执行.

perl -MO=Deparse -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
s/eat/read/g;
Run Code Online (Sandbox Code Playgroud)

好的,-i更改$^I了内联编辑的全局变量,但没有读取文件,这里没有循环.

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

所以-p添加while(){}循环,其中每行读取,由您的代码更改,并再次写入文件(在continue{}块中打印)

perl -MO=Deparse -n -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/eat/read/g;
}
Run Code Online (Sandbox Code Playgroud)

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