GNU/Linux >> Belajar Linux >  >> Linux

Pilih Baris Dari File Teks Yang Memiliki Id Terdaftar Di File Lain?

Saya menggunakan banyak grep awk sort di shell unix saya untuk bekerja dengan file teks kolom yang dipisahkan tab berukuran sedang (sekitar 10M-100M baris). Dalam hal ini unix shell adalah spreadsheet saya.

Tapi saya punya satu masalah besar, yaitu memilih catatan yang diberikan daftar ID.

Memiliki table.csv file dengan format idtfootbar... dan ids.csv file dengan daftar id, hanya pilih catatan dari table.csv dengan id ada di ids.csv .

semacam https://stackoverflow.com/questions/13732295/extract-all-lines-from-text-file-based-on-a-given-list-of-ids tetapi dengan shell, bukan perl.

grep -F jelas menghasilkan positif palsu jika id adalah lebar variabel.
join adalah utilitas yang tidak pernah saya ketahui. Pertama-tama, ini membutuhkan pengurutan alfabet (file saya biasanya diurutkan secara numerik), tetapi meskipun demikian saya tidak dapat membuatnya berfungsi tanpa mengeluh tentang urutan yang salah dan melewatkan beberapa catatan. Jadi saya tidak menyukainya.
grep -f terhadap file dengan ^idt -s sangat lambat ketika jumlah id besar.
awk rumit.

Apakah ada solusi yang baik untuk ini? Adakah alat khusus untuk file yang dipisahkan tab? Fungsionalitas tambahan juga akan disambut baik.

UPD:sort yang dikoreksi -> join

Jawaban yang Diterima:

Saya kira maksud Anda grep -f bukan grep -F tetapi Anda sebenarnya membutuhkan kombinasi keduanya dan -w :

grep -Fwf ids.csv table.csv

Alasan Anda mendapatkan hasil positif palsu adalah (saya kira, Anda tidak menjelaskannya) karena jika sebuah id dapat dimasukkan ke dalam yang lain, maka keduanya akan dicetak. -w menghilangkan masalah ini dan -F memastikan pola Anda diperlakukan sebagai string, bukan ekspresi reguler. Dari 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.)

Jika positif palsu Anda karena ID dapat ada di bidang non-ID, ulangi file Anda sebagai gantinya:

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

atau, lebih cepat:

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

Secara pribadi, saya akan melakukan ini di perl meskipun:

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

Linux
  1. Bagaimana Cara Menghapus Garis Duplikat Di Dalam File Teks?

  2. Ganti Garis yang Mencocokkan Pola Dengan Garis Dari File Lain Secara Berurutan?

  3. Salin N-baris Terakhir Dari Satu File Ke File Lain?

  1. Awk Dari Baris Yang Berbeda?

  2. Buat Data Pembacaan Teks Dari File?

  3. Bagaimana cara menghapus baris baru dari file teks?

  1. Bagaimana cara menghapus garis yang muncul pada file B dari file A lainnya?

  2. Hapus baris ganjil atau genap dari file teks

  3. Hapus N baris pertama dari file log aktif