Accelera grep e scrive su file
Apprezzerei l'aiuto di chiunque. Attualmente, ho 2 file (entrambi formattati allo stesso modo) ed entrambi hanno oltre 2 milioni di righe ciascuno. Esempio di file di seguito:
file 1:
00000001 YYYY
00000002 NYNN
00000003 YNYN
...
...
file 2:
00000001 YYNY
00000002 NYNN
00000003 YNYN
...
...
Quindi nota che la prima riga in ogni file è diversa, quindi stamperei sul file 3:
00000001 YYYY
Per eseguire il processo sopra, ho uno script bash per:
- grep i primi OTTO caratteri per il file 2.
- Confronto l'eco / output di grep con la riga nel file 1.
- SE sono diversi, scrivi la riga (dal file 1) al file 3.
Volevo fornire un codice di esempio, ma tieni presente che l'ho appena inventato al volo MA è lo stesso concetto del mio script. Attualmente, sono in linea 24 ore e solo 240k su 2 milioni. Come posso velocizzarlo in modo efficiente?
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"
Risposte
Sarebbe così semplice con uno script Python.
Python ha la funzione zip che può essere utilizzata per leggere e confrontare due file riga per riga.
Script di Bash di esempio:
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])'
Stampe:
00000001 YYYY
Il vantaggio qui (su un semplice awk
script per esempio) solo una riga di ogni file è nella memoria attiva - le due righe vengono confrontate.
Tuttavia, Unix ha altre soluzioni al problema descritto. Puoi anche usare pasta e awk
:
paste file1 file2 | awk '$2!=$4 {print $1 OFS $2}'
O se i numeri nella prima colonna agiscono come un indice, puoi usare join e awk:
join file1 file2 | awk '$2!=$3 {print $1 OFS $2}'
Oppure il comando comm (sopprimendo col 1 e col 3) se la colonna 1 in ogni file è ordinata funzionerà anche:
comm -1 -3 file1 file2
Tutti e tre i comandi / pipe Unix / Linux producono:
00000001 YYYY