我有一个文本文件,我希望将其转换为 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::CSV
或DBD::CSV
perl 模块。
另请注意,它假设姓氏、名字和中间名各只有一个单词。
#! /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 <(...)
。