Usa un elenco di parole per accedere a un altro elenco


8

Ho un elenco con 250 righe. Devo eseguirli tutti attraverso un server Web per ottenere un elenco di output. Questo elenco, tuttavia, restituisce molte più righe di quelle a cui sono interessato. Supponiamo che il mio list.txtsia:

a.1
b.1
etc

quindi l'output è output.txt:

a.1 a b c
a.2 b a b
a.3 d k o
b.1 b o p
b.2 o i y
b.3 p i y
etc

È possibile utilizzare il comando grep per cercare tutte le parole in list.txt in output.txt e quindi generare l'elenco "desiderato" wanted.txt? Ho bisogno dell'intera riga nel mio output.txt Sono nuovo nello scripting, ma quello che mi piacerebbe è qualcosa di simile

grep list.txt output.txt > wanted.txt

Non sono stato in grado di trovare alcun esempio di questo


Sono entrambi in ordine alfabetico come i tuoi esempi?
Oli

No, ho un ordine non alfabetico specifico nel mio list.txt, ma output.txt è alfabetico, ma mi piacerebbe che contenga solo i "risultati" per il mio list.txt nello stesso ordine non alfabetico
Ditte

Risposte:


11

Ignorerei grepper questo. È buono per le espressioni regolari ma non sembra che tu ne abbia davvero bisogno qui. commpuoi confrontare due file e mostrarti incroci. Usando i tuoi esempi esatti:

$ comm -12 list.txt output.txt 
a.1
b.1
etc

Questo è più veloce di qualsiasi grep, ma si basa (pesantemente) sui file ordinati. In caso contrario, è possibile preordinarli ma ciò modificherà l'output in modo che venga ordinato anche.

comm -12 <(sort list.txt) <(sort output.txt) 

In alternativa, questa risposta di iiSeymour ti consentirà di farlo grep. I flag richiedono un file di input e impongono una ricerca a stringa fissa di parole complete. Questo non si baserà sull'ordine ma si baserà output.txtsull'ordine. Invertire i file se li si desidera nell'ordine di list.txt.

$ grep -wFf list.txt output.txt 
a.1
b.1
etc

Se il tuo list.txtè davvero grande, potresti doverlo affrontare un po 'più iterativamente e passare ogni linea per grep separatamente. Ciò aumenterà notevolmente i tempi di elaborazione. Quanto sopra leggeresti output.txtuna volta, ma in questo modo lo leggeresti ed elaboreresti per ogni riga list.txt. È orribile ... Ma potrebbe essere la tua unica scelta. Sul lato positivo, quindi ordina le cose in base list.txtall'ordine.

$ while read line; do grep -wF "$line" output.txt; done < list.txt
a.1
b.1
etc

1
È davvero intelligente! Qual è la ragione del -12?
Ditte l'

3
-1elimina le righe univoche per il primo file, -2elimina le righe univoche per il secondo file e -3elimina le righe comuni a entrambi. Per ottenere solo le linee comuni, sopprimiamo gli unici, quindi -12.
Oli

simpatico! Penso che userò il comando comm. E poi quando voglio ordinare output.txt per avere lo stesso ordine di list.txt, userò semplicemente il comando -12 <(sort list.txt) <(sort output.txt) in seguito?
Ditte l'

Il comando comm non mi ha fornito l'intera riga in result.txt (e ho bisogno di tutto per ottenere le informazioni da lì). Ma se provo il comando grep mi promette con grep: memoria insufficiente. Significa che è troppo grande?
Ditte l'

il secondo esempio ha un reindirizzamento STDIN ridondante che la shell segnalerebbe come errore. creare file temporanei o usare un file fd aggiuntivo con un ordinamento in background pipeline ad esso (complicato nella maggior parte delle shell) ... questa è più una domanda di programmazione che è meglio porre su Stack Overflow . personalmente, lo farei in Python.
Skaperen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.