筛选CSV文件

筛选CSV文件,csv,sed,awk,grep,Csv,Sed,Awk,Grep,我有一个csv文件和另一个文本文件(比如file1.csv和file2.txt)。文本文件有一列。现在,我想根据文本文件中的数据过滤csv文件。比如说, file1.csv ----------- 1,a,b,c 2,d,e,f 3,g,d,g file2.txt ----------- 1 3 file1.csv ----------- 1、a、b、c 2,d,e,f 3,g,d,g file2.txt ----------- 1. 3. 我希望结果是- 1,a,b,c 3,g,d,g 1、

我有一个csv文件和另一个文本文件(比如file1.csv和file2.txt)。文本文件有一列。现在,我想根据文本文件中的数据过滤csv文件。比如说,

file1.csv ----------- 1,a,b,c 2,d,e,f 3,g,d,g file2.txt ----------- 1 3 file1.csv ----------- 1、a、b、c 2,d,e,f 3,g,d,g file2.txt ----------- 1. 3. 我希望结果是-

1,a,b,c 3,g,d,g 1、a、b、c 3,g,d,g 请尝试以下命令:

awk -F, 'FNR==NR{a[$0];next};$1 in a' file2.txt file1.csv
逻辑很简单:

FOR each line in 'file2.txt' and 'file1.csv'
    IF line is from 'file2.txt'
        store it to array 'a'
        CONTINUE
    ENDIF
    IF column 1 of line is in 'a'
        PRINT line
    ENDIF
ENDFOR

有关使用awk的解决方案,请参阅

使用<代码> GRIP-F 的改进解决方案,考虑使用<代码> BASH < /代码>:

但是,当您指定
-f-
时,并非所有版本的
grep
都读取标准输入(例如,Mac OS X上的版本不读取标准输入,但GNU
grep
读取标准输入)

或者,您可以使用带有适当排序的
join
命令:

join -o 1.1,1.2,1.3,1.4 -t, <(sort file1.csv) <(sort file2.txt)
在Perl中,您可以使用:

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

my $file = 0;
my %rows;

while (<>)
{
    chomp;
    $rows{$_}++ if ($file == 0);
    if ($file == 1)
    {
        my($id) = split /,/;
        print "$_\n" if defined $rows{$id};
    }
}
continue
{
    $file = 1 if eof;
}
#/usr/bin/env perl
严格使用;
使用警告;
我的$file=0;
我的%行;
而()
{
咀嚼;
$rows{$\}++if($file==0);
如果($file==1)
{
我的($id)=拆分/,/;
如果定义了$rows{$id},则打印“$\un”;
}
}
持续
{
如果eof为$file=1;
}
也许还有其他方法可以做到这一点;例如,您可能会发现这样的模块的用途

但是,此代码读取每一行。如果它来自第一个文件,那么它将创建一个条目
$rows{$\u}++
,以记录看到的数字。顺序和重复并不重要。在第二个(和后续)文件中,它将第一个逗号分隔的字段从行中拆分出来,并检查是否在第一个文件中找到该数字;如果是,它将打印整行。
continue
块检测代码何时到达第一个文件的EOF(特别是),并设置
$file=1当它发生时。它与
awk
解决方案同构。这有点冗长。有
-a
模式(
awk
模式),但由于需要对这两个文件进行不同的处理,因此要使其正常工作有点困难

其中,我认为
grep-f
解决方案可能是最整洁的,只要
file2.txt
不是太大(我不确定限制会是什么,但可能会出乎意料地大)


对于通用CSV文件操作工具,考虑.< /P>

尝试下面的命令:

grep-F-F file2.txt file1.csv

1,a,b,c

3、g、d、g和Windows命令版本:

findstr /G:file2.txt file1.csv > result.csv

好啊我能够用简单的“grep”命令解决它。grep-f file2.txt file1.csv。我只是想知道是否还有其他方法。您的简单解决方案还可以从
file1.csv
中选择
10,p,q,r
300,x,y,z
(更不用说
444,1,2,33
);可以吗?如果没有,您需要使用
join
命令,并进行适当的排序,可能是(或者
awk
和关联数组,或者Perl,或者Python,或者
grep-f您可能还想看看[csvfix](一个操作CSV文件的工具。Aargh:我的意思是-)。
join -o 1.1,1.2,1.3,1.4 -t, file1.csv file2.txt
#!/usr/bin/env perl
use strict;
use warnings;

my $file = 0;
my %rows;

while (<>)
{
    chomp;
    $rows{$_}++ if ($file == 0);
    if ($file == 1)
    {
        my($id) = split /,/;
        print "$_\n" if defined $rows{$id};
    }
}
continue
{
    $file = 1 if eof;
}
findstr /G:file2.txt file1.csv > result.csv