GNU/Linux >> Linux の 問題 >  >> Linux

別のファイルにIDがリストされているテキストファイルから行を選択しますか?

UNIXシェルで多くのgrepawkソートを使用して、中サイズ(約10M〜100M行)のタブ区切りの列テキストファイルを処理します。この点で、unixシェルは私のスプレッドシートです。

しかし、私には1つの大きな問題があります。それは、IDのリストを指定してレコードを選択することです。

table.csvがある idtfootbar...形式のファイル およびids.csv IDのリストを含むファイル、table.csvからレコードのみを選択 ids.csvにIDが存在する 。

https://stackoverflow.com/questions/13732295/extract-all-lines-from-text-file-based-on-a-given-list-of-idsの一種ですが、Perlではなくシェルを使用します。

grep -F IDが可変幅の場合、明らかに誤検知が発生します。
join 私が理解できなかったユーティリティです。まず、アルファベット順の並べ替えが必要です(私のファイルは通常、数値で並べ替えられます)が、それでも、間違った順序について不平を言い、一部のレコードをスキップしない限り、機能させることはできません。だから私はそれが好きではありません。
^idtのファイルに対するgrep-f -IDの数が多い場合、sは非常に遅くなります。
awk 面倒です。

これに対する良い解決策はありますか?タブ区切りファイル用の特定のツールはありますか?追加機能も大歓迎です。

UPD:sortを修正しました ->join

承認された回答:

grep -fを意味していると思います grep -Fではありません ただし、実際には両方と-wの組み合わせが必要です :

grep -Fwf ids.csv table.csv

誤検知が発生した理由は(おそらく説明しなかったと思いますが)、IDを別のIDに含めることができる場合は、両方が出力されるためです。 -w この問題を取り除き、-F パターンが正規表現ではなく文字列として扱われるようにします。 man grepから :

   -F, --fixed-strings
          Interpret PATTERN as a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which is to be matched.  (-F is specified by
          POSIX.)
   -w, --word-regexp
          Select  only  those  lines  containing  matches  that form whole
          words.  The test is that the matching substring must  either  be
          at  the  beginning  of  the  line,  or  preceded  by  a non-word
          constituent character.  Similarly, it must be either at the  end
          of  the  line  or  followed by a non-word constituent character.
          Word-constituent  characters  are  letters,  digits,   and   the
          underscore.

   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

IDが非IDフィールドに存在する可能性があるために誤検知が発生した場合は、代わりにファイルをループしてください:

while read pat; do grep -w "^$pat" table.csv; done < ids.csv

または、より速く:

xargs -I {} grep "^{}" table.csv < ids.csv

個人的には、これをperlで行います ただし:

perl -lane 'BEGIN{open(A,"ids.csv"); while(<A>){chomp; $k{$_}++}} 
            print $_ if defined($k{$F[0]}); ' table.csv

Linux
  1. パターンに一致する行を別のファイルの行に順番に置き換えますか?

  2. ファイルからテキスト読み取りデータを作成しますか?

  3. テキスト ファイルから奇数行または偶数行を削除する

  1. nano を使用してファイルからすべてのテキストを選択するにはどうすればよいですか?

  2. 文字列の最初の出現から始めて、大きなファイルからテキストを抽出する方法は?

  3. Linuxでテキストファイルから特定の行を表示するには?

  1. テキストファイル内の重複行を削除するにはどうすればよいですか?

  2. テキストファイルから最初の数行を効率的に削除しますか?

  3. 着信メールをText/plainからText/htmlに変更しますか?