【问题标题】:Remove lines from CSV file that matches lines from another file from bash? [duplicate]从 CSV 文件中删除与 bash 中另一个文件中的行匹配的行? [复制]
【发布时间】:2021-11-01 00:16:12
【问题描述】:

我有一个(大)CSV 文件 (A),其结构如下:

1234ABC 456789
1235ABD 098732
1235ABE 098731
1235ABF 198731

另一个文件 (B) 包含应从 A 中删除的条目:

1234ABC
1235ABE

我想运行一个awksed 命令(或一些命令行脚本,如果awksed 不够用)从A 中删除第一列等于比脚本运行后 A 中的结果应该是:

1235ABD 098732
1235ABF 198731

请注意,仅删除 A 中 B 中任何行开头的行是不够的。例如,如果 A 包含:

1235AC 456789
1235A 098732

而 B 包含:

1235A

那么 A 之后应该包含这个:

1235AC 456789

如何在 bash 中实现这一点,最好使用 awksed(或需要时使用 shell 脚本)?

【问题讨论】:

    标签: awk sed command-line terminal


    【解决方案1】:

    你可以使用这个awk:

    awk 'NR == FNR {dels[$1]; next} !($1 in dels)' file2.csv file1.csv
    
    1235ABD 098732
    1235ABF 198731
    

    这是标准的 2 遍 awk 命令,它将第一遍中 file2 的所有行存储在数组 dels 中。

    在第二遍中,我们只打印来自file1 的行,其中$1 在数组dels 中不存在。

    【讨论】:

      【解决方案2】:
      $ cat fileA
      1234ABC 456789
      1235ABD 098732
      1235ABE 098731
      1235ABF 198731
      1235AC 456789
      1235A 098732
      
      $ cat fileB
      1234ABC
      1235ABE
      1235A
      

      一个grep 想法使用来自文件fileB 的反向单词匹配:

      $ grep -vwf fileB fileA
      1235ABD 098732
      1235ABF 198731
      1235AC 456789
      

      注意:这会将匹配应用于整行(即,不仅仅是第一列),因此如果来自 fileB 的条目可以显示在第 2 列中,则可能会不准确-thru-N of fileA

      【讨论】:

        【解决方案3】:

        使用这个 Perl 单行代码:

        perl -lane 'BEGIN { %exclude = map { chomp; { $_ => 1 } } `cat B`; } print if ! $exclude{ $F[0] };' A
        

        打印:

        1235ABD 098732
        1235ABF 198731
        

        Perl 单行代码使用这些命令行标志:
        -e:告诉 Perl 查找内联代码,而不是在文件中。
        -n:循环输入一行一次,默认将其分配给$_
        -l:在执行内联代码之前剥离输入行分隔符(默认为 *NIX 上的"\n"),并在打印时附加它。-a : 在空白处将$_ 拆分为数组@F

        首先执行BEGIN {...} 块。文件B 的内容存储在哈希%exclude 中,键= 文件B 的行,值= 1。chomp 删除终端换行符。请注意,B 存储在内存中,这对于大文件和小 RAM 可能是个问题。
        -lane :导致脚本逐行循环文件 A,存储空格分隔的字段在数组@F 中。然后,$F[0]A 中每一行的第一列。
        print if ! $exclude{ $F[0] }; :如果在B 中找不到第一个字段($F[0]),则打印A 的行(= not在哈希%exclude)。

        另请参阅:
        perldoc perlrun: how to execute the Perl interpreter: command line switches

        【讨论】:

          猜你喜欢
          • 2016-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-14
          • 2012-07-13
          • 2011-06-14
          • 2019-10-20
          • 2021-05-11
          相关资源
          最近更新 更多