1

csv ファイルと別のテキスト ファイル (file1.csv と file2.txt など) があります。テキスト ファイルには 1 つの列があります。ここで、テキスト ファイルのデータに基づいて csv ファイルをフィルター処理したいと考えています。例えば、

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
4

4 に答える 4

2

このコマンドを試してください:

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
于 2013-08-21T00:27:26.357 に答える
1

を使用した解決策については、 kevによる回答awkを参照してください。

を使用した改善されたソリューションについては、プロセス置換grep -fの使用を検討してください。bash

grep -f <(sed 's/.*/^&,/' file2.txt) file1.csv

これは、各行の先頭にキャレットを置き、最後にカンマを配置するためsedに行で使用file2.txtするため、 (GNU?) によって正規表現として扱われる場合grep、パターンは行の先頭にある正確なフィールド値のみに一致します. をお持ちでない場合はbash、次のものを使用できる場合があります。

sed 's/.*/^&,/' file2.txt | grep -f - file1.csv

ただし、grep指定したときにすべてのバージョンの標準入力が読み取られる-f -わけではありません (たとえば、Mac OS X のバージョンでは読み取れませんが、GNUでは読み取られますgrep)。

joinまたは、適切な並べ替えでコマンドを使用することもできます。

join -o 1.1,1.2,1.3,1.4 -t, <(sort file1.csv) <(sort file2.txt)

ファイルが既にソートされていると確信している場合は、次のように単純化できます。

join -o 1.1,1.2,1.3,1.4 -t, file1.csv 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;
}

おそらく他の方法もあるでしょう。たとえば、Text::CSVなどのモジュールの用途を見つけることができます。

ただし、このコードは各行を読み取ります。最初のファイルからのものである場合は$rows{$_}++、番号が表示されたことを記録するエントリを作成します。順序と繰り返しは関係ありません。2 番目 (およびそれ以降) のファイルでは、最初のコンマ区切りフィールドを行から分割し、その番号が最初のファイルで見つかったかどうかを確認します。その場合は、行全体を出力します。このcontinueブロックは、コードが最初のファイルで (特に) EOF に到達したことを検出し、到達した$file = 1;ときを設定します。awk解と同形です。これは少し冗長です。-aモード (モード)がありawkますが、2 つのファイルを異なる方法で処理する必要があるため、正しく機能させるのは少し難しいです。

grep -fこれらのうち、大きすぎない限り、ソリューションはおそらく最も適切であると思いますfile2.txt(制限がどのくらいになるかはわかりませんが、おそらく驚くほど大きいでしょう)。

汎用の CSV ファイル操作ツールについては、csvfixを検討してください。

于 2013-08-21T04:26:45.007 に答える
0

以下のコマンドを試してください。

grep -F -f file2.txt file1.csv

1,a,b,c
3,g,d,g

于 2013-08-21T05:56:53.263 に答える
0

Windows コマンド バージョンの場合:

findstr /G:file2.txt file1.csv > result.csv
于 2014-02-10T09:18:50.977 に答える