Unix 将固定长度的文件转换为csv文件
我怎样才能:Unix 将固定长度的文件转换为csv文件,unix,csv,awk,sed,Unix,Csv,Awk,Sed,我怎样才能: 将固定长度的文件转换为csv文件 根据列长度从输入文件(固定长度文件)拆分记录 我尝试使用'awk'转换文件,但是由于记录中有空格,结果不正确 输入文件: 4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640 00409164 4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640 00409164 4002000W1ABCDABCD7821 12345
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
00409164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
00409164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
00409164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
00409164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
004009164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
004009164
ABC_ID, def_sc, sde_hd, mln_hfg, ghi_jkl, ijk_klm, pqr_xyz
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
第一条记录从4002000w1abcd7821开始,在
00409164
共有6条记录
输入文件包含表的6条记录
记录中有40多列,我只提到了其中的几列
列的固定长度如下所示:
ABC_ID(9), def_sc(8), sde_hd(8),mln_hfg(12), ghi_jkl(13),ijk_klm(6),pqr_xyz(10)
预期产出如下:
ABC_ID(9), def_sc(8), sde_hd(8),mln_hfg(12), ghi_jkl(13),ijk_klm(6),pqr_xyz(10)
输出文件:
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
00409164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
00409164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
00409164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
00409164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
004009164
4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640
004009164
ABC_ID, def_sc, sde_hd, mln_hfg, ghi_jkl, ijk_klm, pqr_xyz
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164
这是否可以使用sed命令实现
请提出建议。您想要什么还不完全清楚,但GNU awk用于字段宽度和多字符RS是一种选择:
$ awk -v RS='^$' -v FIELDWIDTHS="9 8 8 8" -v OFS=', ' '{gsub(/\n/,""); print $1, $2, $3, $4}' file
4002000W1, ABCDABCD, 78211234, 56789071
下面是一个Perl解决方案:
use strict;
use warnings;
my @fmt = (9, 8, 8, 12, 13, 6, 10);
my @head = qw(ABC_ID def_sc sde_hd mln_hfg ghi_jkl ijk_klm pqr_xyz);
my $rec_len = do { my $sum; for(@fmt) { $sum += $_ }; $sum };
my $fn = 'file';
open(my $fh, '<', $fn) or die "Could not open file '$fn': $!\n";
my $str = do {local $/ = undef; <$fh>};
close($fh);
$str =~ s/\s*//g;
my $regex = join ("", map { "(.{$_})" } @fmt);
my $head_fmt = join (", ", map { "%-". $_ . "s", } @fmt) . "\n";
printf $head_fmt, @head;
while ( $str =~ /(.{$rec_len})/g ) {
my @f = $1 =~ /$regex/;
print join(", ", @f) . "\n";
}
输入文件:
输出文件:
要添加第一行,请首先在BEGIN{…}
中打印它:
awk -v FIELDWIDTHS="9 8 8 12 13 6 10" 'BEGIN{print "ABC_ID, def_sc, sde_hd, mln_hfg, ghi_jkl, ijk_klm, pqr_xyz"} NR%2{temp=$0;next;} {$0=temp$0; gsub(/ /,""); print $1,$2,$3,$4,$5,$6,$7}' OFS=',' file
说明:
指定要打印的字段长度FIELDWIDTHS=“9 8 12 13 6 10”
在NR%2{temp=$0;next;}
变量中存储奇数行(将用于连接这对行)temp
连接每个连续行<代码>$0是当前行,$0=temp$0
是当前行之前的行temp
gsub(//,“”)代码>删除空格字符
按print$1、$2、$3、$4、$5、$6、$7
FIELDWIDTHS
。“56789071……”在哪个字符处停止?。您需要4列或6列来显示这6条记录?感谢您的回复。但是当我在输入文件上使用上述命令时,我得到的输出是:4002000W1ABCD782112345678071001080600W1VUF342116002902291LSN123016030000000000400000000000009164000400000091645012500000000。没有按照指定的长度对记录进行分隔,而是将空格替换为“,”。这实际上不是预期的结果。@user229691您使用的是哪个版本的awk
?@user229691我想您必须安装gawk
才能使用FIELDWIDTHS
谢谢@HåkonHægland,安装“gawk”很有效,但是,它从输入文件中读取一条记录。其余的记录没有被读取。感谢@Hakon脚本,但我需要在shell或gawk中完成。
awk -v FIELDWIDTHS="9 8 8 12 13 6 10" 'BEGIN{print "ABC_ID, def_sc, sde_hd, mln_hfg, ghi_jkl, ijk_klm, pqr_xyz"} NR%2{temp=$0;next;} {$0=temp$0; gsub(/ /,""); print $1,$2,$3,$4,$5,$6,$7}' OFS=',' file