0

我有一个 csv 文件,我想在特定列(我的数据集中的第 5 列)(忽略大小写)中搜索一个字符串columnB,并对另一个columnC(我的数据集中的第 10 列)应用过滤器。然后将选定的列保存到文件中。

数据集样本

columnA     columnB    columnC  columnD
abc          Apple      100     today
nbd          apple      50      tomorrow
ccc          apple      101     today

期望的输出

columnB    columnC
Apple      100
apple      101

我使用时的问题awk我可以选择columnB,但我无法输出标题。

 awk 'BEGIN {IGNORECASE = 1} {if($5 == "Apple") print $0 }' Data.csv> testPipe.txt

我尝试过使用NR==1,但由于某种原因它不适用于IGNORECASE.

我也尝试了这里这里的方法。

我尝试使用grip,我可以输出标题但我无法指定columnB字符串匹配。并且搜索将应用于所有列。

cat Data.csv |{ head -1; grep -I "Apple";} | awk -F',' '{ if ($10 >100 ) { print } }'>testPipe.txt

有没有办法结合这两种方法并获得所需的输出?谢谢

4

2 回答 2

2

使用功能tolower()

awk 'NR==1{print; next} tolower($5) == "apple"' file

解释:

# Print the headers
NR==1 {
    print
    next
}

# Print the current line if $5 matches the condition
# Note that if there is no action specified, awk will
# use print $0 by default
tolower($5)

如果您想在条件为真时编写进一步的操作,请将它们放入一个块中

tolower($5) {
    ...
}

IGNORECASE与仅适用于 GNU awk 的相反,tolower()它将适用于任何版本,awk因为它是由 POSIX 定义的。

于 2019-09-22T07:03:18.937 回答
0

更新:显然我的回答没有我想象的那么好,请参阅下面 Ed Morton 的评论。无论如何,我会保留它,作为“如何不这样做”。

原始(坏)答案:

在设置 IGNORECASE 之前或之后将以下内容添加到您的 BEGIN 子句中:

getline;
print;

解释: BEGIN 子句在其他所有内容之前执行一次,因此您也可以在那里处理行,但您必须手动读取它们。

完整示例:

awk '
    BEGIN {
        getline;
        print;
        IGNORECASE = 1;
    }

    $2 == "apple" && $3 <= 100 {
        print $1;
    }
'
于 2019-09-22T06:36:55.217 回答