【问题标题】:using awk to count characters and modify file accordingly使用 awk 计算字符并相应地修改文件
【发布时间】:2013-02-21 04:23:31
【问题描述】:

我有一个看起来像这样的文件

@FCD17BKACXX:8:1101:2703:2197#0/1
CAGCTTTACTCGTCATTTCCCCCAAGGGTAAAATGCGTCCGTCCATTAAGTTCACAGTCATCGTCT
+FCD17BKACXX:8:1101:2703:2197#0/1
^`^\eggcghheJ`dffhhhffhe`ecd^a^_ceacecfhf\beZegfhh_fghhgfZbdg]c^a`
@FCD17BKACXX:8:1101:4434:2244#0/1
CTGCGTTCATCGCGTTGTTGGGAGGAATCTCTACCCCAGGTTCTCGCTGTGAA
+FCD17BKACXX:8:1101:4434:2244#0/1
eeecgeceeffhhihi_fhhiicdgfghiiihiiihiiihVbcdgfhge`cee
@FCD17BKACXX:8:1101:6394:2107#0/1
CAGCAGGACTAGGGCCTGCAGACGTACTG
+FCD17BKACXX:8:1101:6394:2107#0/1
eeeccggeghhiihiihihihhhhcfghf

我想每隔一行去数一下字符数。如果该行包含少于例如66 个字符,然后用 'A' 填充到 66 并打印到新文件。如果它包含 66 个字符,则按原样打印该行。

输出文件如下所示;

@FCD17BKACXX:8:1101:2703:2197#0/1
CAGCTTTACTCGTCATTTCCCCCAAGGGTAAAATGCGTCCGTCCATTAAGTTCACAGTCATCGTCT
+FCD17BKACXX:8:1101:2703:2197#0/1
^`^\eggcghheJ`dffhhhffhe`ecd^a^_ceacecfhf\beZegfhh_fghhgfZbdg]c^a`
@FCD17BKACXX:8:1101:4434:2244#0/1
CTGCGTTCATCGCGTTGTTGGGAGGAATCTCTACCCCAGGTTCTCGCTGTGAAAAAAAAAAAAAAA
+FCD17BKACXX:8:1101:4434:2244#0/1
eeecgeceeffhhihi_fhhiicdgfghiiihiiihiiihVbcdgfhge`ceeAAAAAAAAAAAAA
@FCD17BKACXX:8:1101:6394:2107#0/1
CAGCAGGACTAGGGCCTGCAGACGTACTGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+FCD17BKACXX:8:1101:6394:2107#0/1
eeeccggeghhiihiihihihhhhcfghfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

我对 awk 有非常基本的了解,所以从学习的角度来看,我想使用 awk 来解决问题。

【问题讨论】:

  • 您在预期输出的最后一行有错字

标签: awk counting


【解决方案1】:

一种方式:

awk '!(NR%2) && length<66{for(i=length;i<66;i++)$0=$0 "A"}1' file

【讨论】:

  • 不错,但您不需要对 "&& length
【解决方案2】:

这应该比公认的方法更快:

awk 'NR%2==0 { x = sprintf("%-66s", $0); gsub(/ /,"A",x); $0 = x }1' file

结果:

@FCD17BKACXX:8:1101:2703:2197#0/1
CAGCTTTACTCGTCATTTCCCCCAAGGGTAAAATGCGTCCGTCCATTAAGTTCACAGTCATCGTCT
+FCD17BKACXX:8:1101:2703:2197#0/1
^`^\eggcghheJ`dffhhhffhe`ecd^a^_ceacecfhf\beZegfhh_fghhgfZbdg]c^a`
@FCD17BKACXX:8:1101:4434:2244#0/1
CTGCGTTCATCGCGTTGTTGGGAGGAATCTCTACCCCAGGTTCTCGCTGTGAAAAAAAAAAAAAAA
+FCD17BKACXX:8:1101:4434:2244#0/1
eeecgeceeffhhihi_fhhiicdgfghiiihiiihiiihVbcdgfhge`ceeAAAAAAAAAAAAA
@FCD17BKACXX:8:1101:6394:2107#0/1
CAGCAGGACTAGGGCCTGCAGACGTACTGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+FCD17BKACXX:8:1101:6394:2107#0/1
eeeccggeghhiihiihihihhhhcfghfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

【讨论】:

  • 处理约 3.1 亿行文件的速度快了 24 分钟。
【解决方案3】:

我会再贴一个奇怪的(也许)oneliner:

 awk 'BEGIN{while(++i<66)t=t"A"}!(NR%2){$0=$0substr(t,length)}1' file

【讨论】:

    【解决方案4】:
    awk 'NR%2 == 0{
        printf("%s", $0)
        for(i=length($0); i<66; i++)printf("A")
        print "";next }
        {print}'
    

    【讨论】:

    • 我没有测试它,但是这会丢失输出中的所有奇数行。正确的?如果我是对的,请修复它。
    • 啊,你是对的。从 OP 的描述来看,是否应该打印奇数行并不是 100% 清楚,但从预期的输出来看,它非常清楚。我已经编辑了我的答案。
    【解决方案5】:
    awk -v FS= '{printf "%s",$0} !(NR%2){for (i=NF+1;i<=66;i++) printf "A"} {print ""}'
    

    或者如果你不喜欢循环:

    awk -v FS= '{sfx=(NR%2 ? "" : sprintf("%*s",66-NF,"")); gsub(/ /,"A",sfx); print $0 sfx}'
    

    【讨论】:

      猜你喜欢
      • 2015-03-19
      • 2014-12-11
      • 2012-11-23
      • 2021-02-23
      • 1970-01-01
      • 2016-12-24
      • 1970-01-01
      • 2011-12-11
      相关资源
      最近更新 更多