File file1.txt berisi baris seperti:
/api/purchase/<hash>/index.html
Sebagai contoh:
/api/purchase/12ab09f46/index.html
File file2.csv berisi baris seperti:
<hash>,timestamp,ip_address
Sebagai contoh:
12ab09f46,20150812235200,22.231.113.64
a77b3ff22,20150812235959,194.66.82.11
Saya ingin memfilter file2.csv menghapus semua baris di mana nilai hash hadir juga di file1.txt. Itu untuk mengatakan:
cat file1.txt | extract <hash> | sed '/<hash>/d' file2.csv
atau sesuatu seperti ini.
Itu harus langsung, tetapi saya tampaknya tidak dapat membuatnya bekerja.
Adakah yang bisa memberikan pipeline yang berfungsi untuk tugas ini?
sumber
cat
, cukupcut -d / -f 4 file1.txt
. Atau jika Anda lebih suka tampilan sekuensial,<file1.txt cut -d / -f 4
awk
Solusi yang mungkin :Pertama kita membaca
file1.txt
menggunakanFS
(pemisah bidang) "/" dan membuat array x dengan nilai kunci dari bidang$4
yang merupakan hash yang Anda inginkan. Selanjutnya kita membacafile2.txt
pengaturan file keduaFS
menjadi,
dan memeriksa apakah nilai field$1
tidak ada sebagai kunci dalam arrayx
dan jika tidak kita cetak.Hal yang lebih idiomatis seperti yang diusulkan dalam komentar dapat berupa:
sumber
!($1 in x)
malah{ if (!($1 in x)) print $0; }
awk
solusi berbasis ... dalam jangka panjang, Anda akan belajar untuk tertarik pada solusi yang dapat dicapai dengan menggunakan pipa yang lebih rendah untuk kesederhanaan ... :)Untuk GNU sed
di mana sed pertama menghasilkan daftar hash dalam format sed-command-like dan mentransfernya ke sed- script berikutnya yang membaca perintah di atas dari input karena itu opsi. Sama dengan grep
/12ab09f46\|a77b3ff22\|..../d
-f -
atau tanpa perl-expresions:
atau bahkan lebih baik dengan potongan :
sumber
Perhatikan bahwa sengatan pencarian adalah
/$key/
dan^$key,
untuk mengurangi hasil menjadi antara dua garis miring (file 1) atau menjadi entri pertama dari sebuah baris dan diikuti oleh koma (file 2). Ini akan membuatnya aman jika kunci terlihat sepertidalam file 2, atau suka
dalam file 1
sumber
Saya baru saja mencoba satu liner berikut, dan sepertinya berhasil:
Silahkan ganti pertama -Ri dengan -re untuk menguji itu. -re melakukan lari kering, dan jika semuanya baik-baik saja Anda dapat menjalankannya dengan -ri
sumber
Selain jawaban Gabriele Lana, harap dicatat bahwa perintah tempel BSD perlu tanda hubung ditentukan untuk membaca konten dari input standar.
manual perintah tempel
Jadi final perlu diubah seperti di bawah ini
sumber