Perl:在$ _中添加一个字符串会产生奇怪的结果

Aji*_*jin 7 string perl

我写了一个超级简单的脚本:

 #!/usr/bin/perl -w
 use strict;
 open (F, "<ids.txt") || die "fail: $!\n";
 my @ids = <F>;
 foreach my $string (@ids) {
 chomp($string);
 print "$string\n";
 }
 close F;
Run Code Online (Sandbox Code Playgroud)

这产生了ids.txt的所有内容的预期输出:

你好

世界

这些

恼人的

源代码

线

现在我想为每一行添加一个文件扩展名:.txt.这条线应该做的伎俩:

 #!/usr/bin/perl -w
 use strict;
 open (F, "<ids.txt") || die "fail: $!\n";
 my @ids = <F>;
 foreach my $string (@ids) {
 chomp($string);
 $string .= ".txt";
 print "$string\n";
 }
 close F;
Run Code Online (Sandbox Code Playgroud)

但结果如下:

.txto

.txtd

.txte

.txtying

.txtcecode

而不是将".txt"附加到我的行,我的字符串的前4个字母将替换为".txt"因为我想检查是否存在某些文件,我需要带扩展名的完整文件名.

我试图砍掉,选择,替换(s/\n //),加入等等.但结果仍然是替代而不是追加.

哪里出错了?

Jim*_*son 15

Chomp不会删除BOTH \r,\n如果文件有DOS行结尾,并且您在Linux/Unix上运行.

您所看到的实际上是原始字符串,回车符和扩展名,它会覆盖显示屏上的前4个字符.

如果传入的文件具有DOS/Windows行结尾,则必须同时删除:

s/\R+$//
Run Code Online (Sandbox Code Playgroud)

  • @Cfreak:你确定在DOS和Windows上`$ /`是`"\ r \n"` 我认为行结尾在输入时只转换为"\n",并在输出时转换回来.这是文本和二进制模式之间的主要区别. (4认同)
  • @Cfreak:你是对的,但他显然是跨平台的.并且_overwrite_我的意思是_在display_,而不是在内存中.在unix系统上尝试`print"abcd\rxyz \n"` - 结果将是`xyzd`. (3认同)
  • `s /\R +\z //`是你想要的. (3认同)
  • @Cfreak,Keith Thompson 100%正确.在Windows上,`$ /`是`"\n"`.Perl默认添加一个`:crlf`层,它在读取时转换CRLF-> LF,在写入时转换LF-> CRLF,因此没有用于删除chomp的\ r \n. (2认同)

bpg*_*rgo 0

你试过这个吗?

foreach my $string (@ids) {
  chomp($string);
  print $string.".txt\n";
}
Run Code Online (Sandbox Code Playgroud)

我不确定你的代码有什么问题。这些结果很奇怪