使用 AWK 过滤 CSV 文件

Filtering CSV File using AWK

我正在处理 CSV 文件

This my csv file

用于过滤的命令awk -F"," '{print }' out_file.csv > test1.csv

这是我的数据示例,看起来我有大约 43 行和 12,000 列 我计划使用 awk 命令分隔单行,但我无法单独分隔第 3 行(疾病)。

我使用以下命令来获取我的输出

awk -F"," '{print }' out_file.csv > test1.csv

这是我的文件:

gender|gene_name  |disease         |1000g_oct2014|Polyphen |SNAP 
male  |RB1,GTF2A1L|cancer,diabetes |0.1          |0.46     |0.1  
male  |NONE,LOC441|diabetes        |0.003        |0.52     |0.6  
male  |TBC1D1     |diabetes        |0.940        |1        |0.9  
male  |BCOR       |cancer          |0            |0.31     |0.2  
male  |TP53       |diabetes        |0            |0.54     |0.4  

注意“|”我没有使用这个分隔符。它用于按顺序显示行我的详细信息在 spreed sheet:

中看起来完全像这样

但我得到的输出如下

Disease
GTF2A1L
LOC441
TBC1D1
BCOR
TP53

在 Spread Sheet 中打开时,我可以以正确的方式获得结果,但是当我使用 awk 时,中间的第 2 行也被获取。我不知道为什么 谁能帮我解决这个问题。

问题的根源是 - 您使用逗号分隔值和嵌入式逗号。

这让生活变得更加艰难。我建议的方法是使用 csv 解析器。

我很喜欢perlText::CSV:

#!/usr/bin/env perl
use strict;
use warnings;

use Text::CSV;

open ( my $data, '<', 'data_file.csv' ) or die $!; 

my $csv = Text::CSV -> new ( { binary => 1, sep_char => ',', eol => "\n" } );

while ( my $row = $csv -> getline ( $data ) ) {
   print $row -> [2],"\n"; 
}

当然,我无法确定这是否真的有效,因为您在 google 驱动器上链接的数据实际上与您提出的问题不符。 (注意 - perl 从零开始数组,所以 [3] 实际上是第 4 个字段)

但它应该可以解决问题 - Text::CSV 可以很好地处理引用的逗号字段。

不幸的是,您提供的 link ("This is my file") 指向两个文件,这两个文件(在撰写本文时)似乎都与您提供的示例不符。但是,如果您的文件确实是一个 CSV 文件,其中逗号用于分隔字段和嵌入字段,那么其他地方给出的使用 CSV 感知工具的建议是非常合理的。 (我会建议考虑一个可以将 CSV 转换为 TSV 的命令行程序,这样整个 *nix 工具链都由您支配。)

您的示例输出和随附的评论表明您可能已经有办法将其转换为竖线分隔或制表符分隔的文件。如果是这样,那么 awk 可以非常有效地使用。 (如果你有选择,那么我建议使用制表符,因为这样 cut 这样的程序特别容易使用。)

那么,一般的想法是将 awk 与“|”一起使用(或制表符)作为主要分隔符(awk -F"|"awk -F\t),并使用 awk 的 split 函数来解析每个顶级字段的内容。

最后,这就是我所做的,以简单的方式得到我的答案,感谢@peak,我找到了解决方案

第一次我用 CSV 过滤器是一个 python 模块,用于过滤 csv 文件。 我使用以下命令

使用 csvfilter 更改了分隔符
csvfilter input_file.csv --out-delimiter="|" > out_file.csv

此命令用于将分隔符“,”更改为“|” 现在我使用 awk 命令进行排序和过滤

awk -F"|" 'FNR == 1 {print} {if ( < 0.01) print }' out_file.csv > filtered_file.csv

感谢您的帮助。