使用Perl从文件中删除某些换行符

时间:2015-06-22 14:50:19

标签: perl shell

我正在使用以下shell脚本来清​​理文件。该文件包含来自数据库的数据记录,但看到某些字段中有新行,导致某些记录分布在两行中,从而导致加载时出现问题。文本用“”括起来并用逗号分隔,所以我使用下面的shell脚本来删除新的行,但在2mil记录文件上大约需要8分钟,从我的理解Perl会更快。

我完全不了解Perl,有人可以在Perl中翻译/解释以下内容吗?

#!/bin/bash

input_file=$1
gawk -v RS='"' 'NR % 2 == 0 { gsub(/\n/, "") } { printf("%s%s", $0, RT) }' $input_file > $input_file"_temp"
mv $input_file"_temp" $input_file

编辑:我无法提供确切的数据,但问题与此类似(由换行符分隔的记录):

"001", "Dave Surname", "1 High Street"
"002", "John Surname", "2 High
Street"
"003", "Bill Surname", "3 High Street"
"004", "James 
Surname", "4 High Street"

根据上述情况,某人在地址栏中添加了一个新行,所以这应该成为:

"001", "Dave Surname", "1 High Street"
"002", "John Surname", "2 High Street"
"003", "Bill Surname", "3 High Street"
"004", "James Surname", "4 High Street"

2 个答案:

答案 0 :(得分:0)

我们需要一些样本数据才能确定。我猜这里发生的事情是你试图解析一个CSV文件,并被记录中的换行符捕获。

这就是为什么基于行/正则表达式的CSV方法通常是一个坏主意的原因之一。值得庆幸的是,在perl中有一个很好的简单解决方案 - Text::CSV模块。

#!/usr/bin/perl

use strict;
use warnings;

use Text::CSV;
my ( $filename ) = @ARGV;

my $csv = Text::CSV->new( { binary => 1, eol => $/ } );

open( my $input, "<", $filename ) or die $!;

while ( my $row = $csv->getline($input) ) {
    foreach my $element (@$row) {
        $element =~ s/\n/ /g;
    }
    $csv->print( \*STDOUT, $row );
}
close($input);

这将迭代命令行中指定的文件名中的每一行 - 并删除嵌入在字段中的所有换行符,同时保留字段外的那些换行符。

答案 1 :(得分:-1)

这会按照你的要求行事。它将每一行追加到变量$r,如果结果包含偶数个双引号,则会打印$r并将其清空

perl -i -lne'unless (($r .= $_) =~ tr/"// % 2) { print $c; $r = ""}' $input_file