我无法修改处理作为命令行参数传递的文件的脚本,仅用于复制这些文件,另外修改这些文件。以下perl脚本适用于复制文件:
use strict;
use warnings;
use File::Copy;
foreach $_ (@ARGV) {
my $orig = $_;
(my $copy = $orig) =~ s/\.js$/_extjs4\.js/;
copy($orig, $copy) or die(qq{failed to copy $orig -> $copy});
}
现在我有名为“* _extjs4.js”的文件,我想将这些文件传递给一个脚本,该脚本同样从命令行获取文件名,并进一步处理这些文件中的行。到目前为止,我能够成功获得文件句柄,如下面的脚本,它的输出显示:
use strict;
use warnings;
foreach $_ (@ARGV) {
print "$_\n";
open(my $fh, "+>", $_) or die $!;
print $fh;
#while (my $line = <$fh>) {
# print $line;
#}
close $fh;
}
哪些输出(部分):
./filetree_extjs4.js
GLOB(0x1a457de8)
./async_submit_extjs4.js
GLOB(0x1a457de8)
我真正想要做的是打印文件句柄的内容,而不是打印文件句柄的表示。一个开始是打印文件行,我是我试过用上面注释掉的代码。
但是该代码没有效果,文件的行不会打印出来。我究竟做错了什么? $ _用于处理命令行参数和用于处理文件内容的参数之间是否存在冲突?
答案 0 :(得分:6)
看起来这里有几个问题。
我真正想要做的是打印文件句柄的表示,而不是打印文件句柄的表示。
print $fh
返回GLOB(0x1a457de8)
的原因是因为标量$fh
是文件句柄而不是文件本身的内容。要访问文件本身的内容,请使用<$fh>
。例如:
while (my $line = <$fh>) {
print $line;
}
# or simply print while <$fh>;
将打印整个文件的内容。
pelrdoc perlop
中记录了这一点:
如果尖括号包含的是一个简单的标量变量(例如,
<$foo>
),然后该变量包含文件句柄的名称 输入,或其typeglob,或对它的引用。
但已经尝试过了!
我可以看到。将打开模式更改为+<
后尝试。
为什么我打开文件读写会把它擦掉?
因为你正在使用这样的东西,它会截断文件 然后给你读写访问权限:
open my $fh, '+>', '/path/name'; # WRONG (almost always)
糟糕。你应该使用它,如果文件将失败 不存在:
open my $fh, '+<', '/path/name'; # open for update
始终使用
">"
clobbers或创建。使用"<"
也不会。该"+"
并未改变这一点。
毫无疑问,强烈建议or die $!
之后的open
。
但退后一步。
有一种更多的Perlish方式来备份原始文件并随后对其进行操作。事实上,它可以通过命令行本身(!)使用-i
标志来实现:
$ perl -p -i._extjs4 -e 's/foo/bar/g' *.js
有关详细信息,请参阅perldoc perlrun
。
我无法满足我的需求。
如果操作对于命令行来说太多了,那么Tie::File
模块值得一试。
答案 1 :(得分:1)
要阅读文件句柄的内容,您必须拨打readline
read
或将文件句柄放在尖括号<>
中。
my $line = readline $fh;
my $actually_read = read $fh, $text, $bytes;
my $line = <$fh>; # similar to readline
要打印到STDIN
以外的文件句柄,您必须将其作为print
的第一个参数,然后是您要打印的内容,而不是它们之间的逗号。
print $fh 'something';
为了防止有人意外添加逗号,我更喜欢将文件句柄放在一个块中。
print {$fh} 'something';
你也可以select
你的新手柄。
{
my $oldfh = select $fh;
print 'something';
select $oldfh; # reset it back to the previous handle
}
同样是open
的模式参数,会导致它破坏文件的内容。此时没有什么可读的。
请改为尝试:
open my $fh, '+<', $_ or die;
答案 2 :(得分:0)
我想为Zaid提出的使用单线的优秀建议添加一些内容。
当你刚接触perl并尝试一些棘手的正则表达式时,为它们使用源文件会很好,因为命令行可能会变得非常拥挤。即:
文件:
#!/usr/bin/perl
use warnings;
use strict;
s/complicated/regex/g;
在调整正则表达式时,请使用源文件,如下所示:
perl -p script.pl input.js
perl -p script.pl input.js > testfile
perl -p script.pl input.js | less
请注意,测试时不要使用-i
标志。这些命令不会更改输入文件,只会将更改打印到stdout。
当您准备好执行(永久!)更改时,只需添加就地编辑-i
标记,如果您愿意(推荐),请提供备份扩展,例如名为 “.bak”。
perl -pi.bak script.pl *.js