Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为空的列添加null_Perl_Awk - Fatal编程技术网

Perl 为空的列添加null

Perl 为空的列添加null,perl,awk,Perl,Awk,我试图使用perl或awk将空列设置为null,以查找列数,可以使用标题的列计数。我尝试使用perl和一些正则表达式来执行解决方案。但是,输出看起来非常接近所需的输出,但是如果仔细注意,第一行显示的数据不正确 输入数据: id name type foo-id zoo-id loo-id-1 moo-id-2 ----- --------------- ----------- ------ ------ ------ ------

我试图使用
perl
awk
将空列设置为null,以查找列数,可以使用标题的列计数。我尝试使用
perl
和一些正则表达式来执行解决方案。但是,输出看起来非常接近所需的输出,但是如果仔细注意,第一行显示的数据不正确

输入数据:

id      name           type          foo-id  zoo-id  loo-id-1  moo-id-2
-----  ---------------  -----------  ------  ------  ------  ------
0      zoo123        soozoo          8               31        32
51     zoo213        soozoo          48      51
52     asz123        soozoo          47      52
53     asw122        soozoo          1003    53
54     fff123        soozoo          68      54
55     sss123        soozoo          75      55
56     ssd123        soozoo          76      56
预期产出:

0      zoo123        soozoo          8       null      31        32
51     zoo213        soozoo          48      51        null      null
52     asz123        soozoo          47      52        null      null
53     asw122        soozoo          1003    53        null      null
54     fff123        soozoo          68      54        null      null
55     sss123        soozoo          75      55        null      null
56     ssd123        soozoo          76      56        null      null
非常接近解决方案,但第1行显示的数据不正确:

echo "$x"|grep -E '^[0-9]+'  |perl -ne 'm/^([\d]+)(?:\s+([\w]+))?(?:\s+([-\w]+))?(?:\s+([\d]+))?(?:\s+([\d]+))?(?:\s+([\d]+))?(?:\s+([\d]+))?/;printf "%s %s %s %s %s %s %s\n", $1, $2//"null", $3//"null",$4//"null",$5//"null",$6//"null",$7//"null"' |column -t
0   zoo123  soozoo  8     31  32    null
51  zoo213  soozoo  48    51  null  null
52  asz123  soozoo  47    52  null  null
53  asw122  soozoo  1003  53  null  null
54  fff123  soozoo  68    54  null  null
55  sss123  soozoo  75    55  null  null
56  ssd123  soozoo  76    56  null  null

使用GNU
awk

awk 'NR>2{                     # ignore first and second row
       NF=7                    # fix number of columns
       for(i=1; i<=NF; i++)    # loop with all columns
         if($i ~ /^ *$/){      # if empty or only spaces
           $i="null"
         }
       print $0}' FIELDWIDTHS='7 14 16 8 8 10 8' OFS='|' file | column -s '|' -t
awk'NR>2{#忽略第一行和第二行
NF=7#固定列数

对于(i=1;i2{NF=7;对于(i=1;i当您要解析一个固定宽度的字符串时,您会发现这是一个比正则表达式更好的工具

这应该演示如何做。我将让您将其转换为一行程序

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

while (<DATA>) {
  next if /^\D/; # Skip lines that don't start with a digit

  # I worked out the unpack() template by counting columns.
  my @data = map { /\S/ ? $_ : 'null' } unpack('A7A14A16A8A8A8A8');

  say join ' ', @data;
}

__DATA__
id      name           type          foo-id  zoo-id  loo-id-1  moo-id-2
-----  ---------------  -----------  ------  ------  ------  ------
0      zoo123        soozoo          8               31        32
51     zoo213        soozoo          48      51
52     asz123        soozoo          47      52
53     asw122        soozoo          1003    53
54     fff123        soozoo          68      54
55     sss123        soozoo          75      55
56     ssd123        soozoo          76      56

您需要按列号拆分数据,因为列之间没有分隔符,任何不在尾随列中的空列都会被误解。这非常痛苦。使用GNU
cut
,您可以使用
cut--output delimiter=''|'-c1-7,8-21,22-37,38-45,46-53,54-63,64-
来获取管道分隔的输出字段。然后找出空字段并用
null
替换数据相当容易。第2行的下划线真的与第1行的标题不对齐吗?这不是针对
gawk
/non-posix吗?此外,您可以从第一行或第二行动态设置
字段宽度(如果可靠的话)谢谢。太神奇了!你能告诉我你是如何计算的
'a7a14a16a8a8a8a8a8'
或者一个简单的资源来阅读吗?官方文件对我来说很难理解。谢谢。@monk:中关于字符串的部分是一个很好的开始。但是它是'a'(意思是将数据当作字符串处理)后跟一个数字,该数字是列的宽度(我通过计算输入数据中的字符数得到)。 0 zoo123 soozoo 8 null 31 32 51 zoo213 soozoo 48 51 null null 52 asz123 soozoo 47 52 null null 53 asw122 soozoo 1003 53 null null 54 fff123 soozoo 68 54 null null 55 sss123 soozoo 75 55 null null 56 ssd123 soozoo 76 56 null null
#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

while (<DATA>) {
  next if /^\D/; # Skip lines that don't start with a digit

  # I worked out the unpack() template by counting columns.
  my @data = map { /\S/ ? $_ : 'null' } unpack('A7A14A16A8A8A8A8');

  say join ' ', @data;
}

__DATA__
id      name           type          foo-id  zoo-id  loo-id-1  moo-id-2
-----  ---------------  -----------  ------  ------  ------  ------
0      zoo123        soozoo          8               31        32
51     zoo213        soozoo          48      51
52     asz123        soozoo          47      52
53     asw122        soozoo          1003    53
54     fff123        soozoo          68      54
55     sss123        soozoo          75      55
56     ssd123        soozoo          76      56
$ perl unpack | column -t
0   zoo123  soozoo  8     null  31    32
51  zoo213  soozoo  48    51    null  null
52  asz123  soozoo  47    52    null  null
53  asw122  soozoo  1003  53    null  null
54  fff123  soozoo  68    54    null  null
55  sss123  soozoo  75    55    null  null
56  ssd123  soozoo  76    56    null  null