Mempercepat grep dan menulis ke file
Saya sangat menghargai bantuan siapa pun. Saat ini, saya memiliki 2 file (keduanya diformat sama) dan masing-masing memiliki lebih dari 2 juta baris. Contoh file di bawah ini:
file 1:
00000001 YYYY
00000002 NYNN
00000003 YNYN
...
...
file 2:
00000001 YYNY
00000002 NYNN
00000003 YNYN
...
...
Jadi perhatikan baris pertama di setiap file berbeda jadi saya akan mencetak ke file 3:
00000001 YYYY
Untuk melakukan proses di atas, saya memiliki skrip bash untuk:
- grep DELAPAN karakter pertama untuk file 2.
- Saya membandingkan echo / output grep dengan baris di file 1.
- JIKA mereka berbeda, tulis baris (dari file 1) ke file 3.
Saya ingin memberikan kode sampel tetapi perlu diingat, saya baru saja membuat ini dengan cepat TAPI konsepnya sama dengan skrip saya. Saat ini, saya 24 jam masuk dan hanya on line 240k dari 2 juta. Bagaimana saya bisa mempercepatnya dengan cara yang efisien?
input="file1"
while IFS= read -r line
do
LineFromFile1=$("${echo $line}") firstEightChars=$("${echo $line:0:8}")
if grep -q "$firstEightChars" file2; then $LineFoundInFile2="$(grep $firstEightCharst file2)"
if [[ $line == $LineFoundInFile2 ]]; then
:
else
echo $line >> file3 done < "$input"
Jawaban
Ini akan sangat sederhana dengan skrip Python.
Python memiliki fungsi zip yang dapat digunakan untuk membaca dan membandingkan dua file baris demi baris.
Contoh skrip Bash:
echo '00000001 YYYY
00000002 NYNN
00000003 YNYN' >file1
echo '00000001 YYNY
00000002 NYNN
00000003 YNYN' >file2
python3 -c '
with open("file1") as f_1, open("file2") as f_2:
for t in zip(f_1, f_2):
if t[0][8:-1] != t[1][8:-1]: print(t[0])'
Cetakan:
00000001 YYYY
Keuntungannya di sini (dibandingkan awk
skrip sederhana misalnya) hanya satu baris dari setiap file dalam memori aktif - dua baris dibandingkan.
Namun, Unix memiliki solusi lain untuk masalah yang dijelaskan. Anda juga dapat menggunakan pasta dan awk
:
paste file1 file2 | awk '$2!=$4 {print $1 OFS $2}'
Atau jika angka di kolom pertama berfungsi sebagai indeks, Anda dapat menggunakan join dan awk:
join file1 file2 | awk '$2!=$3 {print $1 OFS $2}'
Atau perintah comm (menekan col 1 dan col 3) jika kolom 1 di setiap file diurutkan akan berfungsi juga:
comm -1 -3 file1 file2
Ketiga perintah / pipa Unix / Linux menghasilkan:
00000001 YYYY