将文本内容重新格式化为 CSV

将文本内容重新格式化为 CSV

我有一个文本文件,我希望将其转换为 CSV。其内容格式如下:

1 mm/dd/yyyy
LastName, FirstName MiddleName
ID-NUMBER-HERE
GENDER
2 mm/dd/yyyy
LastName, FirstName MiddleName
ID-NUMBER-HERE
GENDER
  • Number 的 1 和 2 是每组的行编号。我想删除它。
  • 日期是生日。有没有办法将其更改为其他格式?
  • 姓名:如果此人有两 (2) 个名字或有前缀怎么办?我希望它们都在一个列中。中间名和姓氏也是如此。

该文件大小为 26MB。

我想要的结果格式是:

'yyyy-mm-dd','LastName','FirstName','MiddleName','ID-NUMBER','GENDER'

有没有办法使用 SED 或其他工具来做到这一点?

我刚刚了解了 SED,如果我尝试自己做,会花费更长的时间。

有人可以帮忙吗?

顺便说一句,我在 Mac 上。

多谢!

阿尔文

答案1

这是一个 perl 脚本,它读取每一行,将它们拆分为字段(在 @line 数组中),并将它们添加到 @out 数组中。当@out中有6个字段时,它会打印出来。

注意:这是非常基本的 CSV,无需引用字符串等 - 除非字段包含字段分隔符(即逗号,),否则不需要引号,。对于更高级的 CSV,需要修改为使用Text::CSVDBD::CSVperl 模块。

另请注意,它假设姓氏、名字和中间名各只有一个单词。

#! /usr/bin/perl

use strict;

my @out = ();
while(<>) {
    my @line = split /,?\s+/;
    my $numfields=@line - 1;
    if ($line[0] =~ m/^\d+$/) {
        push @out, $line[1];
    } elsif ($numfields > 1) {
        push @out, (@line[0..1], join(" ",@line[2..$numfields]));
    } else {
        push @out, @line
    }

    if ( @out == 6 ) { print join(",",@out),"\n" ; @out=() } ;
}

示例输出(使用保存为的示例输入input.txt

$ ./convert-to-csv.pl input.txt 
mm/dd/yyyy,LastName,FirstName,MiddleName,ID-NUMBER-HERE,GENDER
mm/dd/yyyy,LastName,FirstName,MiddleName,ID-NUMBER-HERE,GENDER

答案2

使用paste

$ paste -d '|' - - - - <data.in >data.tmp1
$ cat data.tmp1
1 mm/dd/yyyy|LastName, FirstName MiddleName|ID-NUMBER-HERE|GENDER
2 mm/dd/yyyy|LastName, FirstName MiddleName|ID-NUMBER-HERE|GENDER

现在,当我们有了这个时,我们可以过滤掉第一个字段中的数字,并将第二个字段中的任何逗号或空格替换为|

$ awk -F '|' 'BEGIN { OFS=FS } { gsub("^[0-9]* ", "", $1); gsub("[, ]+", "|", $2); print }' data.tmp1 >data.tmp2
$ cat data.tmp2
mm/dd/yyyy|LastName|FirstName|MiddleName|ID-NUMBER-HERE|GENDER
mm/dd/yyyy|LastName|FirstName|MiddleName|ID-NUMBER-HERE|GENDER

要重新格式化日期:

$ awk -F'/' '{ printf("%s-%s-%s\n", $3, $1, $2) }' <( cut -d'|' -f1 data.tmp2 )
yyyy-mm-dd
yyyy-mm-dd

这可以替换为数据:

$ paste -d '|' \
    <( awk -F'/' '{ printf("%s-%s-%s\n", $3, $1, $2) }' <( cut -d'|' -f1 data.tmp2 ) ) \
    <( cut -d '|' -f 2- data.tmp2 ) >data.tmp3
$ cat data.tmp3
yyyy-mm-dd|LastName|FirstName|MiddleName|ID-NUMBER-HERE|GENDER
yyyy-mm-dd|LastName|FirstName|MiddleName|ID-NUMBER-HERE|GENDER

如果你有csvkit,这可以转换为正确引用和逗号分隔的 CSV:

$ csvformat -d '|' -D ',' -U 2 <data.tmp3
"yyyy-mm-dd","LastName","FirstName","MiddleName","ID-NUMBER-HERE","GENDER"
"yyyy-mm-dd","LastName","FirstName","MiddleName","ID-NUMBER-HERE","GENDER"

上述解决方案需要一个能够理解进程替换的 shell <(...)

相关内容