从文件中提取数据并操作内容以写入新文件

从文件中提取数据并操作内容以写入新文件

我有一个 csv 文件,我从中提取与我相关的数据。一方面是参考号,另一方面是字母 G、A、T 和 C 形式的遗传信息。

内容 csv:

1,S188823,188823,,,,ACTCTCGA,,CTGTACCA,ID23,
1,S189843,189843,,,,ACCCTGGA,,CTTGTACA,ID23,
...

与我相关的信息188823,,,,ACCCTGGA,,CTTGTACA 来自每一行。在此过程中必须删除重复项。前两行也必须被截断。

这就是我目前所做的:

cat File.csv | cut -d "," -f 3,9,7 | uniq | sed -e '1d' -e '2d'

结果如下:

188823,ACTCTCGA,CTGTACCA
189843,ACCCTGGA,CTTGTACA
...

但现在有两件事必须做,而我却失败了。字段 3 和字段 2 必须交换

188823,CTGTACCA,ACTCTCGA
189843,CTTGTACA,ACCCTGGA
...

现在从 field2 开始,碱基必须“反向互补”,这意味着每个 A 变成 T,每个 C 变成 G,每个 G 变成 C,每个 T 变成 A,并且序列顺序颠倒。所以,CTGTACCA变成TGGTACAG.

最终结果必须如下所示:

188823,TGGTACAG,ACTCTCGA
188823,TGTACAAG,ACCCTGGA

我希望这是可以理解的并且你可以帮助我。可以在此处找到有关反向补体构建的一些帮助: 在线 RevComp 生成器

答案1

使用 GNU awk

awk -F, '!seen[$3 FS $9 FS $7]++ {
    cmd="echo \047" $9 "\047 | rev | tr ATCG TAGC";
    if ((cmd |getline $9)>0){ print $3, $9, $7; };
    close(cmd);
}' OFS=, infile

输出:

188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

添加NR>2到命令中,就像awk 'NR>2{ ...; }'跳过输入中的前两行一样。

这里我们使用了[getline从管道转换为变量] 中包含预定义的命令cmd="..." $9 "..." (请注意,我们只将与外部命令相关的内容放在双引号内),然后从 Pipe to 调用它getline并将结果保存到同一$9字段中;然后,如果getline结果成功,我们会在输出中打印所需的字段。

最后我们应该关闭(指令命令我们打开了。

!seen[$3 FS $9 FS $7]++用于忽略处理字段 #3、#9 和 #7 上的重复行。

答案2

$ cat tst.awk
BEGIN {
    FS=OFS=","
    map["A"] = "T"
    map["C"] = "G"
    map["G"] = "C"
    map["T"] = "A"
}
{
    str = ""
    for (i=1; i<=length($9); i++) {
        str = map[substr($9,i,1)] str
    }
    print $3, str, $7
}

$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

或者如果您想在 awk 中tr输入rev函数:

$ cat tst.awk
BEGIN { FS=OFS="," }
{ print $3, rev(tr($9,"ACGT","TGCA")), $7 }

function tr(oldStr,oldChars,newChars,   i,pos,oldChar,newStr) {
    for (i=1; i<=length(oldStr); i++) {
        oldChar = substr(oldStr,i,1)
        pos     = index(oldChars,oldChar)
        newStr  = newStr (pos ? substr(newChars,pos,1) : oldChar)
    }
    return newStr
}

function rev(oldStr,    i,newStr) {
    for (i=1; i<=length(oldStr); i++) {
        newStr = substr(oldStr,i,1) newStr
    }
    return newStr
}

$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

或者只是一个同时执行这两项操作的函数:

$ cat tst.awk
BEGIN { FS=OFS="," }
{ print $3, trev($9,"ACGT","TGCA"), $7 }

function trev(oldStr,oldChars,newChars, i,pos,oldChar,newStr) {
    for (i=1; i<=length(oldStr); i++) {
        oldChar = substr(oldStr,i,1)
        pos     = index(oldChars,oldChar)
        newStr  = (pos ? substr(newChars,pos,1) : oldChar) newStr
    }
    return newStr
}

$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

答案3

我们可以用perl这个。

  • 用逗号分割行并将字段存储在零索引数组中@F
  • 将列表分隔符$,和列表连接符设置$"为逗号。
  • 反转第 9 个元素的字符$F[8],然后应用字符翻译。
$ perl -F, -lane '
    BEGIN { $, = $" = ","; }
    print $F[2], reverse($F[8]) =~ tr/ATGC/TACG/r, $F[6]
      if $. > 2 && !$h{"@F[2,6,8]"}++;
' file
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

相关内容