linux shell脚本中如何统计某一行中某字符出现的个数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux shell脚本中如何统计某一行中某字符出现的个数相关的知识,希望对你有一定的参考价值。

比如

2340 3 1 1 1 0 1 3 2
2341 1 0 1 1 3 0 0 3
2342 1 1 3 0 0 0 0 1
2343 1 0 0 0 3 0 1 3
2344 2 0 1 1 1 0 1 0
2345 0 2 2 0 0 1 1 0
2346 0 2 2 1 1 3 2 2
2347 0 0 3 2 2 1 1 1
下面这几行中,我如何统计2340行中3 ,1 ,0 分别出现的个数,下面的以此类推。
我搜索了了相关命令行如gerp awk 等发现只能提取某个文档中指定字符出现的总数,或者打印出出现一个或者多个字符的指定行,却没法做到单个字符在一行中精确的统计并将其显示打印出来。比如打印出包含2个3,3个3个1的行,是不是我忽略了某个命令行的参数,感谢回答。

1、统计某个字符的个数,以a为例
grep -o a urifle
awk -F "" 'for(i=1;i<=NF;++i) if($i=="a") ++sumENDprint sum' urfile
#-F ""中间必须要有空格 "a"必须使用双引号,字符串
awk -F "" 'for(i=1;i<=NF;i++)a[$i]++ENDfor(j in a) if(j=="c") print a[j]' urfile
#
2、储存在变量里
echo "0001111" |tr -cd 1 |wc -c
如果有时间可以看看《Linux就该这么学》,里面有各种Linux相关知识
参考技术A awk 'for(i=1; i<=NF;++i)if($i==1||$i==3||$i==0)num[$i]++for(key in num)printf "%d:%d\t",key,num[key]printf "\n"'追问

让上图达到下图的结果

简而言之就是按顺序统计每一行 3 2 1 0的个数 并在该行后面显示出来

追答

awk 'for(key in num)num[key]=0for(i=1; i=0;--i)printf "%d ",num[i]printf "\n"'

求一段perl或者shell程序,用来计算一个文件中某段字符的长度有多长。

例:1.txt
>a123
abcddccbaadbcdabcddcdbabbdcbaadbdabdbabddbabdbcbdbabdbbcdbdcbababsddbbcdbbaacdbcdb

>b234
1123 debcgebc gdbegcbd grgrdbc ghebrgcb egrbcgrb rgcrhrgb bgcbdnge bfngdbdn dhghekaj sdsdsdwa

求其中不包含>的行的字符的长度,只自算有效字符,不包含空格和数字

PERL来做这个很简单,你没有明确输出内容的格式,下面的代码你可能需要调整输出部分:

open(FD,\'1.txt\');
while($s=<FD>)
    if ($s =~ /^[>]/)
        $s2=$s;
        $s2 =~ s/[^a-zA-Z]//g;
        print length($s2)."\\t".$s;
    

close(FD);

上面的代码读出文件的每一行,对不以>开头的行进行处理,替换到26个字母之外的内容,计算长度,输出长度和原始内容。

追问

输出内容‘>xxx:(字符长度),格式为txt,文件中包含多个">xxx assdasdadasd"的段落,从">"到下一个“>”之前为1段,每统计1段1输出。 拜托了!能OK的话我加分!拜托!

追答

你说的我没懂(如果你给一个输入文件、输出内容的示例,我相信我还是能看懂的),你看看下面的代码是不是你要的:

open(FD,\'1.txt\');
while($s=<FD>)
    if ($s =~ /^[>]/)
        $s2=$s;
        $s2 =~ s/[^a-zA-Z]//g;
        print ">".length($s2)."\\t".$s;
    

close(FD);追问

输入为1.txt:
>dinB
1 atgcgtaaaa tcattcatgt ggatatggac
61 aatcctgccc tgcgcgatat ccctattgct
>icdA

ATGGAAAGTAAAGTAGTTGTTCCGGCACAAGGCAAGAAGATCA

输出为1-r.txt:>dinB:60
>icdA:43

追答

这下明白的了,和你题目的要求相差很远,以下代码测试通过,保证和你的要求一致:

my($key,$len,$s);
open(FD,"1.txt");
open(FE,">1-r.txt");
$key=\'\';
$len=0;
while($s=<FD>)
  chomp($s);
  if (substr($s,0,1) eq \'>\')
    print FE "$key:$len\\n" if ($key ne \'\');
    $key=$s;
  else
    $s =~ s/[^a-zA-Z]//g;
    $len+=length($s);
  

print FE "$key:$len\\n";
close(FE);
close(FD);追问

我有多个类似文档,怎样使上面的程序可已批量处理啊?

我有1.txt 2.txt 3.txt ...怎样批量处理而不用自己一个个去修改输入?

追答

单个文件的处理满足你要求了没,满足了可以套个循环实现多文件处理,例如:

my($i,$key,$len,$s);
for ($i=1;$i<=3;$i++)
    open(FD,"$i.txt");
    open(FE,">$i-r.txt");
    $key=\'\';
    $len=0;
    while($s=<FD>)
      chomp($s);
      if (substr($s,0,1) eq \'>\')
        print FE "$key:$len\\n" if ($key ne \'\');
        $key=$s;
      else
        $s =~ s/[^a-zA-Z]//g;
        $len+=length($s);
      
    
    print FE "$key:$len\\n";
    close(FE);
    close(FD);

第二行是新添加的,里面的文件名以前的1修改为$i,其它基本上没变。

参考技术A awk 'if(/^>/)nextgsub(/[0-9 ]/,"",$0)i+=length($0)ENDprint i' 1.txt

以上是关于linux shell脚本中如何统计某一行中某字符出现的个数的主要内容,如果未能解决你的问题,请参考以下文章

Shell脚本中计算字符串长度的5种方法及从文本获取某一行

如何利用JAVA代码实现文件中某一行中某一段字符串的修改?

统计一段长字符串中某字符串的出现次数

labview如何读取文本文档中某一行的字符串

如何在shell脚本中修改添加替换指定文件中的内容

shell脚本里怎么替换掉某个文件的最后一行的最后一个字符