• Perl区分文件换行符类型


    背景

    在Windows上使用Perl判断文件时何种换行符时,处理CR LF类型的换行符时,也识别成了LF。

    思路

    1. Windows上的换行是 CRLF , Unix上是 LF , Mac CR
    2. 在Windows平台使用Perl读取文件创建文件句柄时,未对file handler设置binmode,了解到binmode模型作用是采用非二进制读取模式时,双字节换行符CR LF在读取时转换为LF,写入时将LF转换为CR LF。这对于使用双字节分隔文本文件行的操作系统(MS-DOS)至关重要,但对使用单个字符的操作系统(Unix,Mac OS,QNX)没有影响。
    3. chomp是去除每行行末的记录分隔符(record separator),这个分隔符的值是可以通过 perl内置变量 $/ (input record separators )来设置,默认情况下Windows和Linux上 $/ 的值都是 LF

    处理

    所以Perl脚本在读取DOS文本时,行末换行符CR LF 被自动转行成 LF ,此后去判断单行记录时,返回结果均是LF,未能正确识别出文件的换行符类型,基于此原因。修改代码如下(测试)

    #!/usr/bin/perl
    
    use strict;
    
    my $path = '/export/script/perl_scripts';
    
    my @files = qw /a.txt b.txt/;
    
    my $newLine = '';
    
    for my $f (@files)
    {
        my $fullPath = sprintf "%s/%s",$path,$f;
    
        # 获取首行
        open(INFILE,$fullPath) or die "dont open this file ${fullPath}";
    
        # 此函数设置在操作系统上以二进制形式读取和写入FILEHANDLE的格式。
        # 采用非二进制读取模式时,双字节换行符CR LF在读取时转换为LF,写入时将LF转换为CR LF。
        # 这对于使用双字节分隔文本文件行的操作系统(MS-DOS)至关重要,但对使用单个字符的操作系统(Unix,Mac OS,QNX)没有影响。
        binmode(INFILE); # 设置二进制读取模式,保留文件中的原始换行符
        my $line = ;
        close INFILE;
    
        if($line =~ '\r\n')
        {
            $newLine = 'CRLF';
            print "windows newline\n";
        }elsif($line =~ '\n')
        {
            $newLine = 'LF';
            print "linux newline\n";
        }elsif($line =~ '\r')
        {
            $newLine = 'CR';
            print "mac newline\n";
        }else
        {
            print "is a single line without newline\n";
        }
        print "${fullPath} newline is ${newLine}\n";
    
        # 采用如下去除换行符方式,替换chomp方法,可在任意平台处理任意换行符类型的文件
        $line =~ s/[\r\n]+\Z//g;
    
    }
    ## 运行结果如下
    # linux newline
    # /export/script/perl_scripts/a.txt newline is LF
    # windows newline
    # /export/script/perl_scripts/b.txt newline is CRLF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    思路源自:https://blog.csdn.net/fibonaccian/article/details/42168725

  • 相关阅读:
    软考网络工程师每日一练10.17
    .NET周刊【6月第1期 2024-06-02】
    二、VSCode——MiKTeX编写latex编码
    3.【刷爆LeetCode】找出字符串中第一个只出现一次的字符(多方法、多思路)
    语法基础(函数)
    Spring5源码3-BeanDefinition
    Windows OpenGL ES 波浪特效
    计算机视觉中的数据预处理与模型训练技巧总结
    在组件中显示tuku的照片
    FOR ALL ENTRIES 优化
  • 原文地址:https://blog.csdn.net/jinYwuM/article/details/133103414