如何使用 unix select 具有特定值的列

How to select columns with specific values using unix

我有以下示例制表符分隔文件:

.CvR    Col_1    Col_2    Col_3    Col_4    Col_5
S1    1    0    1    0    1
S2    1    1    1    0    1
S3    1    1    1    1    1
S4    1    0    1    1    1
S5    1    0    1    1    1

我正在尝试想出一种简单的方法来打印第一列和所有只有“1”值的列。

我想要的输出文件应该是这样的:

.CvR   Col_1    Col_3    Col_5
S1    1    1    1
S2    1    1    1
S3    1    1    1
S4    1    1    1
S5    1    1    1

我的实际输入文件会大很多。我想尽可能在​​ UNIX 中执行此操作。有人可以帮忙吗?谢谢

你在找这个吗?

awk '{ print  " "  " "  " "  " "  }' file

.CvR Col_1 Col_3 Col_5 
S1 1 1 1 
S2 1 1 1 
S3 1 1 1 
S4 1 1 1 
S5 1 1 1 

你已经知道输入文件有多少行,所以只需简单地获取每列的总和并与最后一行索引减去 1(列的总和)进行比较。

#!/bin/bash
# colSum is the last line index minus 1
cat input.txt | awk -v colSum=5 '{
    NR != 1
    for (i = 2; i <= NF; ++i) {
        sumOfCol[i] += $i
    } 
}
END {
    for (i in sumOfCol) {
        if (sumOfCol[i] == colSum)
            print i
    }
}'

执行此操作后,可以获得您需要的列的索引。也许这是一个简单的方法。

我认为最好的方法是读取 Excel 中的 csv 文件,计算每列的总和并手动删除不需要的列。

使用 sed 成为一种肮脏且缓慢的解决方案。 sed 解决方案的想法是将任何 0 或 1 值(@Lee:是的,我对您的 post 的评论对我也有效,awk 似乎是更好的解决方案)更改为具有列号和值的字段.
您可以计算值 1 出现的频率,并在它与总行数不匹配时删除该列。 变量值包含一个将与 0 或 1 匹配的表达式,并将存储在内存中以用于 \1 构造。

#!/bin/bash
clear
value='\([01]\)'
cp file file2
for i in 1 2 3 4 5 6; do
        sed -i "s/ ${value}/ val${i}_/"  file2
done
rowcount=$(wc -l <file2)
for i in 1 2 3 4 5 6; do
        if [ $(grep -c val${i}_1 file2) -eq ${rowcount} ]; then
                sed -i "s/val${i}_./1/"  file2
        else
                sed -i "s/Col_${i}//"  file2
                sed -i "s/val${i}_.//"  file2
        fi
done
cat file2