大型二进制文件($ data)的摘录如下所示:
\n1ax943021C xxx\t2447\t5
\n1ax951605B yyy\t10400\t6
\n1ax919275 G2L zzz\t6845\t6
前25个字符包含一个用空格填充的商品编号。如何将文章编号和下一列之间的所有空格转换为\ x09?请注意商品编号不同部分之间的一个或多个空格。
我尝试了一种解决方法,但用“。{25} xxx»”覆盖了文章编号。
$data =~ s/\n.{25}/\n.{25}xxx/g
任何人都可以提供帮助吗?
非常感谢!
加里
答案 0 :(得分:2)
您可以将unpack
用于固定宽度数据:
use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Useqq=1;
print Dumper $_ for map join("\t", unpack("A25A*")), <DATA>;
__DATA__
1ax943021C xxx 2447 5
1ax951605B yyy 10400 6
1ax919275 G2L zzz 6845 6
<强>输出:强>
$VAR1 = "1ax943021C\txxx\t2447\t5";
$VAR1 = "1ax951605B\tyyy\t10400\t6";
$VAR1 = "1ax919275 G2L\tzzz\t6845\t6";
请注意Data::Dumper
Useqq
选项会以转义形式打印白字符。
基本上我在这里做的是取每行,解压缩它,使用2个空格填充文本字符串(删除所有多余的空格),将这些字符串连接到tab并打印出来。另请注意,这会保留最后一个字符串中的空格。
答案 1 :(得分:1)
我将这个问题解释为有一个25个字符宽的字段,它的尾部空格应该被剥离,然后在下一个字段之前用制表符分隔。否则应保留文章编号中的空格(例如“1ax919275 G2L”)。
以下构造应该可以解决这个问题:
$data =~ s/^(.{25})/{$t=$1;$t=~s! *$!\t!;$t}/emg;
匹配数据中每行开头的25个字符,然后通过剥离其尾随空格并附加制表符来评估每个商品编号的表达式。
答案 2 :(得分:0)
尝试使用:
$data =~ s/ +/\t/g;
答案 3 :(得分:0)
不确定你到底是什么 - 这将匹配两列并打印出来 - 与所有原始空间。让我知道所需的输出,我会为你解决...
#!/usr/bin/perl -w
use strict;
my @file = ('\n1ax943021C xxx\t2447\t5', '\n1ax951605B yyy\t10400\t6',
'\n1ax919275 G2L zzz\t6845\t6');
foreach (@file) {
my ($match1, $match2) = ($_ =~ /(\\n.{25})(.*)/);
print "$match1'[insertsomethinghere]'$match2\n";
}
输出:
\n1ax943021C '[insertsomethinghere]'xxx\t2447\t5
\n1ax951605B '[insertsomethinghere]'yyy\t10400\t6
\n1ax919275 G2L '[insertsomethinghere]'zzz\t6845\t6