【问题标题】:Perl To Parse Whitespace Separated ColumnsPerl 解析空格分隔的列
【发布时间】:2016-11-23 20:34:27
【问题描述】:

我有一个大文本文件,其中包含三列,每列由四个空格分隔。我需要一个 perl 脚本来读取这个文本文件并将列 #1 和 #2 输出到一个新的文本文件,其中每一列都用引号括起来,并在输出文件中用逗号分隔。

包含四列的文本文件的数据如下所示:

    9a2ba3c0580b5f3799ad9d6f487b2d3    /folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg    HOST

我希望输出的样子是

"9a2ba3c0580b5f3799ad9d6f487b2d38","/folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg"

【问题讨论】:

    标签: perl parsing whitespace


    【解决方案1】:

    以下代码供您参考:

    #!/usr/bin/perl
    my $defaultFileName=defined $ARGV[0]?$ARGV[0]:"filename.txt";
    die "Could not find file: $defaultFileName" unless(-f $defaultFileName);
    open my $fh, '<',"textFileName.log";
    foreach my $line(<$fh>) {
        my @tmpData=split(/\s+/, $line);
        printf "\"%s\",\"%s\"\\n\n",$tmpData[1],$tmpData[2];
    }
    close $fh;
    

    【讨论】:

    • 1) 你应该检查open 的成功,而不是用-f 检查文件是否存在:open my $fh, '&lt;', $file or die $!; 现在你有一个竞争条件。 2) 您可以使用split(' ', $line) 忽略前导空格。 3) Perl 有字符串插值,所以除非你需要做特殊的格式化,print/say 一般比printf 更可取。在这种情况下,我会更进一步并使用map + join,例如my @fields = split(' ', $line); say( join(',', map qq{"$_"}, @fields) ); 或类似的东西。 4) 总是use strict;use warnings 'all';
    【解决方案2】:

    像单线一样简单:

    perl -lane 'print join ",", map qq("$_"), @F[0, 1]'
    
    • -l 处理 print 中的换行符
    • -n逐行读取输入
    • -a 将空白处的每一行拆分为 @F 数组
    • @F[0, 1] 是一个数组切片,它提取@F 数组的前两个元素
    • map 将每个元素用双引号括起来
    • join 在中间插入逗号

    【讨论】:

    • 似乎不起作用。这是我得到的输出: String found where operator expected at parse4.pl line 2, near "lane 'print join ",", map qq("$_"), @F[0, 1]'" (Do你需要预先声明lane吗?)parse4.pl第2行的语法错误,靠近“lane 'print join”,map qq(“$_”),@F[0, 1]'” parse4.pl的执行中止由于编译错误。我正在使用 Perl v5.18.2。
    • @QuePID:在 shell 中运行整行并附加文件名。这不是一个脚本,它是一个单行。
    • 单线效果很好,如何转换成脚本?
    • @QuePID:将shebang行改为#!/usr/bin/perl -lan,将print join ',', map qq("$_"), @F[0, 1]放在第二行。
    • 如果我想使用固定的文件名并将输出通过管道传输到新文件怎么办?如果我运行脚本并将文件名传递给它以进行解析,然后手动通过管道传输到新文件,它就可以工作。
    【解决方案3】:

    这也可以通过awk来完成

    >>cat test
    9a2ba3c0580b5f3799ad9d6f487b2d3    /folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg    HOST
    9a2ba3c0580b5f3799ad9d6f487b2d3    /folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg    HOST
    9a2ba3c0580b5f3799ad9d6f487b2d3    /folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg    HOST
    9a2ba3c0580b5f3799ad9d6f487b2d3    /folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg    HOST
    

    输出:

    >>awk '{FS="    "}{print "\""$1"\",""\""$2"\",""\""$3"\"" }' test
    "9a2ba3c0580b5f3799ad9d6f487b2d3","/folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg","HOST"
    "9a2ba3c0580b5f3799ad9d6f487b2d3","/folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg","HOST"
    "9a2ba3c0580b5f3799ad9d6f487b2d3","/folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg","HOST"
    "9a2ba3c0580b5f3799ad9d6f487b2d3","/folder1/folder2/folder3/folder4/folder5/folder6/folder7_name_PC/images/filename.jpg","HOST"
    
    >>awk '{FS="    "}{print "\""$1"\",""\""$2"\",""\""$3"\"" }' test > output.txt
    

    然后output.txt 将有一个期望的输出。

    【讨论】:

    • 它也可以用 Ruby、Python、Java、C++ 和 C 等来完成,但这不是问题所要问的。
    猜你喜欢
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 2013-06-03
    • 1970-01-01
    相关资源
    最近更新 更多