我有一个包含约 320 行和约 1800 列 (1.9 MB) 的数据文件 ( data.txt
),我需要提取某些列(对于所有行)。总体布局data.txt
如下:
ID Adipocyte - breast, donor2.CNhs11969.11327-117E4 ....
HGNC:8888 0 ....
HGNC:9999 123.92 ....
HGNC:1000 9.31 ....
我有一个需要提取的列的列表(在文件中list.txt
),但该列表仅由列术语中的 CNhsXXXXX 标识符组成(即对于上面的示例,该列表仅包含CNhs11969,不是整个术语脂肪细胞-乳房,供体2.CNhs11969.11327-117E4)。
我以前曾使用 grep 来获取行列表,但从未使用过列列表。我四处寻找,但找不到使用多个术语来 grep 多列的方法。我对 unix 还很陌生(我是一名生物学家,在计算方面经验很少),所以我不确定 grep 是否可以做到这一点。
任何帮助,将不胜感激。
编辑:我的示例输出仅为 ~1800 列中的 ~850 列(仅包含我list.txt
文件中的术语)。示例:如果我的列表仅包含 CNhs5006 和 CNhs7021,我只希望标题中包含这些术语的列。的示例data.txt
:
ID XXXCNhs5006XXX XXXCNhs6025XXX XXXCNhs7021XXX XXXCNhs8095XXX
HGNC:1111 1.23 1.53 9.21 0
HGNC:2222 1.95 73.92 0 123.29
所需输出的示例:
ID XXXCNhs5006XXX XXXCNhs7021
HGNC:1111 1.23 9.21
HGNC:2222 1.95 0
我的list.txt
只是一个简单的术语列表(1 列,约 850 行,每行包含 1 个搜索词)。例子:
CNhs1111 CNhs2222 CNhs3333 CNhs4444
答案1
我想OP可以做到以下几点:
- 读取标题
data.txt
并将列转换为行 Grep
获取要匹配的数字的行list.txt
- 通过
data.txt
cut
如果列是制表符分隔的,则脚本可以是:
cut -f 1,$(
head -n1 data.txt |
tr '\t' '\n' |
grep -nf list.txt |
sed ':a;$!N;s/:[^\n]*\n/,/;ta;s/:.*//'
) data.txt
答案2
你可以尝试这样的事情:
awk -F'\t' -f script.awk column.names data
哪里script.awk
:
NR == FNR { columns[NR] = $0; next }
NR > FNR && FNR == 1 {
for (i = 1; i <= NF; i++) {
for (j = 1; j < NR; j++) {
if ($i ~ columns[j]) {
selected[i] = 1;
break;
}
}
}
}
{
for (i = 1; i <= NF; i++) {
if (i in selected) printf $i "\t";
}
print "";
}
@Costas 的方法很巧妙。不过,我认为可以稍微简化一下:
head -n1 data | tr '\t' '\n' | grep -nf column.names | cut -f1 -d: \
| paste -sd, | xargs -I{} cut -f {} data