Windows和Linux环境下,文件换行符不同导致错误:行尾出现^M

1.忽略标题,看看以下问题

file1.txt file2.txt file3.txt是Windows下用Notepad++生成的三个小文件,现在将它们拷贝到Linux下面。
它们的内容分别是:

$ head file*
==> file1.txt <==
ABC
ABCD
ABCDE

==> file2.txt <==
George  120
Peppa   130
Susy    140

==> file3.txt <==
Susy
Peppa
Danny
Richard
George
  1. file1是几行字符串,待会儿需要输出它们的长度
  2. file2和3是含有名字的文件,待会儿需要根据file2的内容,判断file3中各个名字是否在file2中出现
2.问题1:求字符串长度
$ cat 1.pl 
#! /usr/bin/perl
use warnings;
use strict;

open my $fh1, "<", "file1.txt";
while (<$fh1>) {
    chomp $_;
    print length($_)."\n";
}
close $fh1;

$ perl 1.pl 
4
5
6

字符串长度都比实际值多1,用命令行试一下

$ awk '{print length($0)}' file1.txt 
4
5
6

还是多1
这种情况下如果在主程序中运用了if+字符串长度判断,可能永远也不会得到想要的结果。

3.问题2:查找字符串
$ cat 2.pl 
#! /usr/bin/perl
use warnings;
use strict;

open my $fh1, "<", "file2.txt";
my %name_exists = ();
while (<$fh1>) {
    chomp $_;
    my @oneline = (split(/\t/, $_));
    $name_exists{$oneline[0]} = 1;
}
close $fh1;

open my $fh2, "<", "file3.txt";
while (<$fh2>) {
    chomp $_;
    if (exists $name_exists{$_}) {
        print "$_\t出现过\n";
    } else {
        print "$_\t没有出现过\n";
    }
}
close $fh2;

$ perl 2.pl 
Susy    没有出现过
Peppa   没有出现过
Danny   没有出现过
Richard 没有出现过
George  没有出现过

问题出在哪里

4.Windows和Linux环境下,文件换行符不同

在windows下的文本文件的每一行结尾,都有一个回车('\n')和换行('\r')
在linux下的文本文件的每一行结尾,只有一个回车('\n');

可以在Notepad++中看到这种区别:菜单栏选择“视图”——“显示符号”——“显示所有字符”。
Windows文件行尾显示

Linux文件行尾显示

Linux终端下面也能看到区别

awk '{print $1"---"}' file1.txt | less
#显示
ABC^M---
ABCD^M---
ABCDE^M---

awk '{print $1"---"}' file3.txt | less
#显示
Susy^M---
Peppa^M---
Danny^M---
Richard^M---
George^M---

这就是为什么会出错的原因

每行多了一个^M
这导致字符串长度+1
也导致$hash{"Peppa"}变成了$hash{"Peppa^M"}, 问题2中的名字都识别不了
5.怎么避免这个问题?

在Linux下面生成一个文件(需要简单输入几个字符,比如1换行2换行3),拖到Windows下面,用Notepad++打开后清空内容,将原文件的内容(比如这里的file1.txt)复制拷贝到这上面,再重新命一个名即可(比如file1_new.txt)。这样这个新文件在Linux和Windows下面都能正常被Perl处理。

另外可以使用命令行, 效果相同

dos2unix file3.txt
sed -i 's/\r//g' file2.txt

我的疑问:是否可以在脚本中识别这种^M的情况,并在脚本中解决它,欢迎在下方评论指出,谢谢!


reference

https://hlee.iteye.com/blog/1476195

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351