linux - 如何根据另一列过滤矩阵

标签 linux bash matrix awk

我想使用另一个文件中的列来过滤矩阵文件。

我有 2 个制表符分隔的文件。其中之一包括矩阵。我想根据 FileB 的第一列过滤我的矩阵文件。如果此矩阵文件 (FileA) 的标题(列名称)出现在文件 B 的第一列中,我想过滤它们以在新文件中使用。我可以尝试的所有解决方案都是基于过滤行,而不是字段。任何帮助表示赞赏。谢谢!

文件A

   A B C D E F G H I J K L M N
R1 0 0 0 0 0 0 0 0 0 1 0 0 1 1
R2 1 1 0 1 0 0 0 0 1 0 1 0 0 0 
R3 0 0 0 0 0 0 0 0 0 0 0 0 0 1
R4 1 1 0 1 0 0 0 1 0 1 0 1 0 0
R5 0 0 0 0 1 0 1 0 1 0 1 0 1 0 

文件B

A Green
B Purple
K Blue
L Blue
Z Green
M Purple
N Red
O Red
U Red

我的预期输出是:

预期输出

   A B K L M N
R1 0 0 0 0 1 1
R2 1 1 1 0 0 0 
R3 0 0 0 0 0 1
R4 1 1 0 1 0 0
R5 0 0 1 0 1 0 

最佳答案

哦,到底是什么,我不确定让你发布 R 脚本除了满足我迂腐的需要之外真的会有什么不同,所以在这里:

$ cat tst.awk
NR == FNR {
    outFldNames2Nrs[$1] = ++numOutFlds
    next
}
FNR == 1 {
    $0 = "__" FS $0
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        outFldNr = outFldNames2Nrs[$inFldNr]
        out2inFldNrs[outFldNr] = inFldNr
    }
}
{
    printf "%s", $1
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) {
        inFldNr = out2inFldNrs[outFldNr]
        if (inFldNr) {
            printf "%s%s", OFS, $inFldNr
        }
    }
    print ""
}

$ awk -f tst.awk fileB fileA
__ A B K L M N
R1 0 0 0 0 1 1
R2 1 1 1 0 0 0
R3 0 0 0 0 0 1
R4 1 1 0 1 0 0
R5 0 0 1 0 1 0

我使用术语“字段名称”来表示每列顶部的字母(awk 中的“字段”)。尝试通过查看手册页并在有用时添加“打印”来自己弄清楚剩下的内容,然后如果有任何问题,请随时提出问题。

我在标题行的前面添加了 __ ,这样每行输出中的列数都相同 - 这使得传递到其他工具进行进一步操作变得更容易,但如果您不喜欢,也可以很容易地调整代码以不这样做。

关于linux - 如何根据另一列过滤矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57402773/

相关文章:

c# - 来自单声道的奇怪的未处理异常

php - 从 php exec() 运行 bash 脚本

c - 将 GSL 数组传递给其他函数

linux - 为什么我可以创建比 "free memory"/"thread stack size"更多的线程?

c - 在文件描述符上使用 fwrite/将文件描述符转换为文件指针

linux - 从管道将值读入 shell 变量

list - 为什么我得到 "Exception: Prelude.head: empty list"?

r - 为变量中的每个唯一元素创建一个转换矩阵

linux - 如何编写包含=的systemd环境变量值

bash - Jenkins Pipeline Step withEnv 在没有 BASH 的情况下无法工作