字符串索引处理

字符串索引处理

我的输入文件如下所示:

#key    string              pos(string)     
key1    AA000AA000000AAA0A  2, 3, 18, 12    
key2    00A00AAA000AAAA00A  3, 18           

我想在每个关键行的末尾添加一个新列(制表符分隔)。如果A在输入文件的第 2 列中找到 an,则新列将包含输入文件的第 3 列中给出的位置。如果0在输入文件的第 2 列中找到 a,则不应在新列中打印该位置。

基本上,这是期望的输出:

#key    string              pos(string)     Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12    2, 18
key2    00A00AAA000AAAA00A  3, 18           3, 18

简短说明:
(键1)

  • 索引 2 处的字符串在新列中添加 了一个A-> 项2
  • 索引 3 处的字符串有一个0-> item3 不是添加到新列
  • 索引 12 处的字符串有一个0-> 项12 不是添加到新列
  • 索引 18 处的字符串在新列中添加了一个A-> 项18

我正在 python 中执行此操作,但我陷入了多个键和项目的困境(字符串处理起来很长),所以我想我可以向您寻求命令行(更轻量级)解决方案的建议。

我的想法是:

  • 拆分 pos(string) 字段,获取我在字符串字段中搜索的索引
  • 获取字符串中给定索引处的字符
  • for 语句(?)

答案1

下面的脚本怎么样awk

#!/usr/bin/awk -f
BEGIN {
        FS="\t"
        print "#key\tstring\tpos(string)\tApos(string)"
}

{
        out=""
        printf "%s\t",$0
        split($2,str,"")
        gsub(/ /,"",$3)
        split($3,pos,",")
        for (i in pos){
                if (str[pos[i]]=="A"){
                        out = out pos[i] ", "
                }
        }
        gsub(/, $/,"",out)
        print out
}

将其另存为(例如)findA.awk并使其可执行chmod +x findA.awk

然后针对您的输入数据运行它并将输出重定向到一个新文件:

./findA.awk input.txt > output.txt
cat output.txt
#key    string  pos(string) Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12    2, 18
key2    00A00AAA000AAAA00A  3, 18   3, 18

输出不像您的示例那么整洁,因为它是制表符分隔的(根据您的要求),并且制表符宽度与各种字符串的宽度不对齐。

答案2

我不确定你现在是如何做的(查看你的 Python 代码会很有帮助),但你可以创建第 3 列的元素列表,这些元素指向第 2 列中的“A”,如下所示:

[i for i in COLUMN3 if COLUMN2[i]=='A']

这似乎是一个简单的问题,但也许我并不完全理解。也许您忘记了字符串是可迭代的?

答案3

一个可怕的perl

$ perl -anle '
    printf "%s    Apos(string)\n",$_ and next if /^#/;
    printf "%s",$_;
    $len = 12 - length((split(/\s+/,$_,3))[-1]);
    for $pos_ss (@F[2..$#F]) {
        $char = substr($F[1],int($pos_ss)-1,1);
        push @res, int($pos_ss) if $char eq 'A';
    }
    printf "%@{[12-4+$len]}s\n", join ", ",@res;
    @res=();
' file
#key    string              pos(string)    Apos(string)
key1    AA000AA000000AAA0A  2, 3, 18, 12   2, 18
key2    00A00AAA000AAAA00A  3, 18          3, 18

它的工作原理与我的解决方案类似这个答案,加上添加$len变量来计算需要打印最后一列对齐的格式。

相关内容