如何使用AWK删除包含特定标题的所有列

时间:2012-09-13 09:08:54

标签: awk gawk

我有一个csv文件当然是以逗号分隔,并希望删除所有具有特定标题的列,例如:

voltage, current, power, voltage, current, power
      2,       3,     6,      12,      12,   144  
      3,       5,    15,      10,      10,   100  

应该是

voltage, power, voltage, power  
      2,     6,      12,   144  
      3,    15,      10,   100  

4 个答案:

答案 0 :(得分:2)

script.awk的内容:

BEGIN {
    FS=" , "
}

NR==1 {
    for (i=1; i<=NF; i++) {
        if ($i == "current") {
            array[i]++
        }
        else {
            printf (i != NF) ? $i", " : $i
        }
    }
}

NR>=2 {
    for (j=1; j<=NF; j++) {
        if (!(j in array)) {
            printf (j != NF) ? $j", " : $j
        }
    }
}

{
    printf "\n"
}

file.txt的内容:

voltage , current , power , voltage , current , power
2 , 3 , 6 , 12 , 12 , 144
3 , 5 , 15 , 10 , 10 , 100

运行如:

awk -f script.awk file.txt

结果:

voltage, power, voltage, power
2, 6, 12, 144
3, 15, 10, 100

答案 1 :(得分:1)

如果要删除所有标题为“current”的列:

kent$  awk -F',' 'NR==1{for(x=1;x<=NF;x++)if($x!="current")l[x]++;}{for(i=1;i<=NF;i++)if(i in l)printf (i==NF)?$i"":$i", ";printf "\n"}' test.txt 

voltage, power, voltage, power
2, 6, 12, 144
3, 15, 10, 100

注意:我删除了上面test.txt中的空格。

  • 如果您需要删除不同的标题。您可以尝试使用Regex,并将$x!="foo"替换为正则表达式匹配。

  • 如果您知道删除列的规则,例如第2列,第5,第8 ......(+ 3),则可以更容易处理,例如循环。

答案 2 :(得分:0)

假设输入文件名是input.txt

awk  -F ',' '{print $1 "," $3 "," $5 "," $6 }' input.txt

答案 3 :(得分:0)

请注意,对于常规CSV文件处理,应使用正确的库。如果数据非常简单,即没有嵌入的逗号,换行符等,可以使用更简单的工具。

你有来自 steve 的良好awk解决方案,所以我将根据coreutils和grep添加答案:

# find columns to remove
pattern=current
cols=$(head -n1 a.csv | tr ',' '\n' | grep -n "$pattern" | cut -d: -f1 | paste -s -d,)

# remove all columns that matched
cut --complement -d, -f$cols a.csv

输出:

voltage, power, voltage, power
2 , 6 , 12 , 144
3 , 15 , 10 , 100

请注意,--complement选项是GNU剪切扩展。要为其他剪辑生成$cols,应该这样做(在FreeBSD上的zsh中测试):

# number of columns
file=a.csv
pattern=current
n=$(head -n1 "$file" | tr ',' '\n' | wc -l)

# generate complementary list
cols=$(jot $n \
| grep -xvFf <(head -n1 "$file" | tr ',' '\n' | grep -n "$pattern" | cut -d: -f1) \
| paste -s -d, -)

# remove columns
cut -d, -f$cols "$file"