当我匹配特定列时使用gsub

时间:2016-06-10 14:35:06

标签: bash awk string-substitution

我有一个原始文件,其中包含一个DNA碱基序列表,包含行标签和列标签,以及一个单独的“位置”文件,列出了列标签的子集。我需要处理原始文件,对位置文件标识的列执行转换。

示例原始文件:

name pos1 pos2 pos3 pos4 pos5 pos6 pos7
name1 AT TA CT GT CC TC TT
name2 AA TA TT GT TC TC TT
name3 AT TT CG AT CT TC TT
name4 GT TA CT TT CC TC TT

示例位置文件:

pos1
pos3
pos6
pos7

在每个选定的字段上,我需要执行这些翻译:

A to T
C to G
G to C
T to A

因此,通过基于提供的位置文件处理示例原始文件而获得的输出将是:

name pos1 pos2 pos3 pos4 pos5 pos6 pos7
name1 TA TA GA GT CC AG AA
name2 TT TA AA GT TC AG AA
name3 TA TT GC AT CT AG AA
name4 CA TA GA TT CC AG AA

因此第一行未经修改,并且在每个后续行中,对应于列标签pos1pos3pos6pos7的字段将被转换,而其他字段保持不变。

我知道如何使用awk来修改整个输入行或修改n th 字段,但我只需修改列出的那些字段在位置文件中,由数据文件第一行的列标签标识。如何在gsub()

中实现该功能

2 个答案:

答案 0 :(得分:1)

假设保留精确的字段(列)分隔符并不是必需的 - 也就是说,您可以自由地将每个列分隔符更改为固定字符串,例如单个空格 - 您可以使用{{1在每个字段的基础上,然后重建记录。这样可以解决限制特定字段更改的问题。

另一个问题是根据位置文件和列标题中的数据识别要修改的字段。这是一种方法:

  • 使用QGraphicsTextItem块,从位置文件中读取每一行并将其内容记录为数组索引。您可以将此视为记录哈希表中每行的内容。

  • 通过循环遍历字段并检查它们是否存在于标签数组中,将预读取列标签与从主输入的第一行读取的列标签匹配。对于那些存在的,将字段 number 记录为第二个数组中的索引

  • 对于每个后续行,从其组成字段重建记录,根据字段编号是否记录为需要转换的字段之一,在原始值和修改值之间进行选择。

    < / LI>
  • 特别注意gsub()可以通过存储在变量中的字段编号来引用字段。因此,BEGIN生成与awk

  • 相同的输出

myfield = 2; print $myfield程序执行所有可能如下所示的操作:

print $2

答案 1 :(得分:1)

$ cat tst.awk
BEGIN {
    split("A T C G G C T A",t)
    for (i=1;i in t;i+=2) {
        map[t[i]] = t[i+1]
    }
}
NR==FNR {
    fldNames[$1]
    next
}
FNR==1 {
    for (i=1;i<=NF;i++) {
        if ($i in fldNames) {
            targets[i]
        }
    }
}
FNR>1 {
    $0 = tolower($0)
    for (fldNr in targets) {
        for (old in map) {
            gsub(tolower(old),map[old],$fldNr)
        }
    }
    $0 = toupper($0)
}
{ print }

$ awk -f tst.awk positions original
name pos1 pos2 pos3 pos4 pos5 pos6 pos7
NAME1 TA TA GA GT CC AG AA
NAME2 TT TA AA GT TC AG AA
NAME3 TA TT GC AT CT AG AA
NAME4 CA TA GA TT CC AG AA