0

我有一个包含多列和多行的 CSV [File1.csv]。

我有另一个 CSV 文件(只有一列),其中列出了特定的单词 [File2.csv]。

如果任何列与 File2 中列出的任何单词匹配,我希望能够删除 File1 中的行。

我最初使用这个:

 grep -v -F -f File2.csv File1.csv > File3.csv

这在一定程度上奏效了。我遇到的这个问题是包含多个单词的列(例如 word1、word2、word3)。File2 包含 word2 但没有删除该行。

我厌倦了将单词分开看起来像这样:(word1,word2,word3),但原始命令不起作用。

如何从 File2 中删除包含单词并且可能包含其他单词的行?

4

2 回答 2

1

一种使用方式awk

内容script.awk

BEGIN {
    ## Split line with a doble quote surrounded with spaces.
    FS = "[ ]*\"[ ]*"
}

## File with words, save them in a hash.
FNR == NR {
    words[ $2 ] = 1;
    next;
}

## File with multiple columns.
FNR < NR {
    ## Omit line if eigth field has no interesting value or is first line of
    ## the file (header).
    if ( $8 == "N/A" || FNR == 1 ) {
        print $0
        next
    }

    ## Split interested field with commas. Traverse it searching for a
    ## word saved from first file. Print line only if not found.

    ## Change due to an error pointed out in comments.
    ##--> split( $8, array, /[ ]*,[ ]*/ )
    ##--> for ( i = 1; i <= length( array ); i++ ) {
    len = split( $8, array, /[ ]*,[ ]*/ )
    for ( i = 1; i <= len; i++ ) {
    ## END change.

        if ( array[ i ] in words ) {
            found = 1
            break
        }
    }
    if ( ! found ) {
        print $0
    }
    found = 0
}

假设File1.csv并且在Thor 的File2.csv回答的评论中提供了内容(我建议将该信息添加到问题中),请运行如下脚本:

awk -f script.awk File2.csv File1.csv

具有以下输出:

"DNSName","IP","OS","CVE","Name","Risk"
"ex.example.com","1.2.3.4","Linux","N/A","HTTP 1.1 Protocol Detected","Information"
"ex.example.com","1.2.3.4","Linux","CVE-2011-3048","LibPNG Memory Corruption Vulnerability (20120329) - RHEL5","High"
"ex.example.com","1.2.3.4","Linux","CVE-2012-2141","Net-SNMP Denial of Service (Zero-Day) - RHEL5","Medium"
"ex.example.com","1.2.3.4","Linux","N/A","Web Application index.php?s=-badrow Detected","High"
"ex.example.com","1.2.3.4","Linux","CVE-1999-0662","Apache HTTPD Server Version Out Of Date","High"
"ex.example.com","1.2.3.4","Linux","CVE-1999-0662","PHP Unsupported Version Detected","High"
"ex.example.com","1.2.3.4","Linux","N/A","HBSS Common Management Agent - UNIX/Linux","High"
于 2012-07-13T16:54:13.640 回答
0

您可以将包含多个模式的分割线转换为File2.csv.

下面用于tr将包含的行转换word1,word2为单独的行,然后再将它们用作模式。该<()构造临时充当文件/fifo(在 中测试bash):

grep -v -F -f <(tr ',' '\n' < File2.csv) File1.csv > File3.csv
于 2012-07-13T16:53:27.950 回答