-2

我编写了一个用于映射两个数据集的 perl 脚本。当我使用 Linux 终端运行程序时,输出混乱。看起来输出是重叠的。我正在使用 Fedora 25。我已经在 Windows 上尝试过代码,它运行良好。

同样的问题也存在于 Ubuntu 上。

期望:

亚当 123 约翰 321

汤姆 473 本特利 564

等等....

我得到的输出:

亚当 123N 321

汤姆 473TLY 564

等等......

我已经在 Windows 上测试了代码,它工作得很好。尽管在 Ubuntu 16.04 上仍然存在同样的问题。

请帮忙。

代码:

use warnings;

open F, "friendship_network_wo_weights1.txt", or die;
open G, "username_gender_1.txt", or die;

while (<G>){
    chomp $_;
    my @a = split /\t/, $_;
    $list{$a[0]} = $a[1];
}
close G;

while (<F>){
    chomp $_;
    my @b = split /\t/, $_;
    if ((exists $list{$b[0]}) && (exists $list{$b[1]})){
        $get =  "$b[0]\t${list{$b[0]}}\t$b[1]\t${list{$b[1]}}\n";
        $get =~ s/\r//g;
        print "$get";
    }
}

close F;
4

1 回答 1

1

问题出在 Windows 上,换行符是\r\n. 其他一切都是\n. \r假设这些文件是在 Windows 上创建的,当您在 Unix上阅读它们时,每一行在chomp.

\r是“回车”字符。就像在一台旧打字机上,您必须将整个打字头移回一行末尾的左侧,计算机显示器曾经是称为 Teleprinters 的精美打字机。打印时,光标会移回行首。之后打印的任何内容都会被覆盖。这是一个简单的例子。

print "foo\rbar\r\n";

你会看到的是bar. 这是因为它打印...

  1. foo
  2. \r将光标返回到行首
  3. bar覆盖foo
  4. \r将光标返回到行首
  5. \n转到下一行的开头(无论光标在哪里)

chomp只会删除$/字符串末尾的任何内容。在 Unix 上是\n. 在 Windows 上是\r\n.

有很多方法可以解决这个问题。最安全的方法之一是使用正则表达式手动删除这两种类型的换行符。

# \015 is octal character 015 which is carriage return.
# \012 is octal character 012 which is newline
$line =~ s{\015?\012$}{};

这表示在行尾删除可能 a\r并且绝对 a 。\n

于 2017-02-05T20:51:49.170 回答