首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在bash中查找和打印特定字符

如何在bash中查找和打印特定字符
EN

Stack Overflow用户
提问于 2016-09-05 13:40:34
回答 3查看 430关注 0票数 1

我有这样的档案:

代码语言:javascript
运行
复制
AA,A=14,B=356,C=845,D=4516
BB,A=65,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,F=225

我从来不知道在行中是否遗漏了A,B,C或D值。但我需要转换这个文件如下:

代码语言:javascript
运行
复制
AA,A=14,B=356,C=845,D=4516,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,-,-,F=225

因此,如果有任何值丢失,只需打印-标记。我的计划是拥有相同数量的列以便于解析。我更喜欢awk解决方案。谢谢你的建议或帮助。

我的第一次尝试是:

代码语言:javascript
运行
复制
awk '{gsub(/[,]/, "\t")}; BEGIN{ FS = OFS = "\t" } { for(i=1; i<=NF; i++) if($i ~ /^ *$/) $i = "-" }; {print $0}'

但我注意到,有些价值观缺失了。

编辑:

从我的头上我知道有值A,B,C,D,E,F.

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-09-05 15:15:40

代码语言:javascript
运行
复制
$ cat file.txt
AA,A=14,B=356,C=845,D=4516
BB,A=65,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,F=225

$ perl -F, -le '@k=(A..F);
   $op[0]=$F[0]; @op[1..6]=("-")x6;
   $j=0; for($i=1;$i<=$#F;){ if($F[$i] =~ m/$k[$j++]=/){$op[$j]=$F[$i]; $i++} }
   print join(",",@op)
   ' file.txt
AA,A=14,B=356,C=845,D=4516,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,-,-,F=225
  • -F,,上拆分输入行并保存到@F数组
  • -l从输入行中删除换行符,将换行符添加到输出
  • @k=(A..F);AB等对@k数组进行初始化,直至F
  • $op[0]=$F[0]; @op[1..6]=("-")x6;使用@F的第一个元素和剩下的6个元素作为-来初始化@op数组
  • 循环遍历@F数组,如果元素与相应索引中的@k数组元素匹配,则更改@op元素。
  • print join(",",@op)打印以,为分隔符的@op数组
票数 3
EN

Stack Overflow用户

发布于 2016-09-05 15:15:50

Perl来救我!

您还没有指定如何获取标头信息,因此在下面的脚本中,@header数组将直接填充。

%to_idx散列将列名映射到它们的索引(A => 0、B => 1等)。

每一行被分割成字段,每个字段与预期的字段($next)进行比较,并在需要时打印破折号。对于缺失的拖尾字段,情况也是如此。

代码语言:javascript
运行
复制
#!/usr/bin/perl
use warnings;
use strict;

my @header = qw( A B C D E F );

my %to_idx = map +($header[$_] => $_), 0 .. $#header;

open my $IN, '<', shift or die $!;
while (<$IN>) {
    chomp;
    my @fields = split /,/;
    print shift @fields;
    my $next = 0;
    for my $field (@fields) {
        my ($name, $value) = split /=/, $field;
        print ',-' x ($to_idx{$name} - $next);
        print ",$name=$value";
        $next = $to_idx{$name} + 1;
    }
    print ',-' x (1 + $#header - $next);  # Missing trailing fields.
    print "\n"
}
票数 2
EN

Stack Overflow用户

发布于 2016-09-06 13:08:21

代码语言:javascript
运行
复制
BEGIN {                                  
    PROCINFO["sorted_in"]="@ind_str_asc" # order for for(i in a)
    for(i=65;i<=90;i++)                  # create the whole alphabet to array a[]
        a[sprintf("%c", i)]              # you could read the header and use that as well
}
{
    split($0,b,",")                      # split record by ","
    printf "%s", b[1]                    # printf first element (AA, BB...)
    delete b[1]                          # get rid of it
    for(i in b) 
        b[substr(b[i],1,1)]=b[i]         # take the first letter to use as index (A=12)
    for(i in a)                          # go thru alphabet and printf from b[]
        printf "%s%s", OFS, (i in b?b[i]:"-"); print ""
}

awk -v OFS=\, -f parsing.awk tbparsed.txt
AA,A=14,B=356,C=845,D=4516,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-
CC,A=88,B=54,C=549,-,-,F=225,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-

它为记录中没有找到的每一个字母打印"-“。如果数据有头部,可以将split转换为二维数组b[NR],并将for(i in a)更改为for(i in b[1]) ... printf ... b[NR][b[1][i]] ...,如果不需要静态第一列,则删除第一个printfdelete

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39331907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档