Ricerca multipla e sostituzione di azioni in un unico file di testo


11

Ho un grande file di testo (circa 2 GB). Voglio fare cinque ricerche e sostituire azioni sullo stesso file e vorrei farlo in un solo comando. Normalmente uso vim, apro il file, eseguo un'azione di sostituzione, quindi la successiva, ecc. C'è un problema, poiché ho notato che dopo tre o quattro ricerche vim si arresta in modo anomalo a causa di problemi di memoria.

Ecco due esempi del comando che uso in Vim:

:%s/www\.abcdef/www.test.abcdef/g 
:%s/www\.klmnop/www.test.klmnop/g

Qual è il modo migliore per gestirlo?

Risposte:


8

Vorrei usare sed in questo modo:

sed -i "s/www\.abcdef/www.test.abcdef/g;s/www\.kmlnop/www.test.klmnop/g;" yourfile.txt

-il'opzione sta per sostituzione "sul posto". Puoi dire a sed di creare un backup del tuo file fornendo un'estensione a questa opzione ( -i.bakeseguirà il backup di yourfile.txt come yourfile.txt.bak).


È veloce! Non solo la tua risposta ;-), ma questo script con 5 ricerche e sostituzioni è circa 10 volte più veloce come solo aprendo il file in vim. Una cosa però mi ha confuso. All'inizio ho pensato che il file .bak sarebbe stato il file modificato, ma ovviamente è l'originale.
SPRBRN,

Dieci azioni di ricerca e sostituzione (con migliaia di hit) in un file da 2 GB in una volta, senza problemi di memoria. Meno di due minuti su un desktop medio - super!
SPRBRN,

Una domanda ... Sfuggi ai punti nella stringa di sostituzione. È necessario?
SPRBRN,

1
Prego @rxt :) In realtà, hai ragione, puoi usare punti non sfuggiti nella stringa di sostituzione in sed. Ho provato e funziona. C'è un buon thread in Unix e Linux Stackexchange e la risposta accettata non menziona i punti come caratteri da scappare.
ssssteffff, l'

2
@rxt hai detto di sostituire la stringa, scusa, non è necessario sfuggirle lì.
terdon,

6

Se hai molti più schemi di ricerca, puoi salvarli in un file e leggere le sostituzioni da lì. Ad esempio, supponiamo che questi siano i contenuti di replacements.txt:

www\.abcdef www.test.abcdef 
www\.klmnop www.test.klmnop

È quindi possibile leggere un elenco di N sostituzioni e sostituirle con queste:

while read from to; do
  sed -i "s/$from/$to/" infile.txt ; 
done < replacements.txt 

APPUNTI:

  • Ciò presuppone che le stringhe di ricerca non contengano spazi e che sia necessario sfuggire a eventuali caratteri strani replacements.txt.
  • Ne eseguirà uno sedper sostituzione che potrebbe richiedere del tempo se si hanno molte operazioni di sostituzione.
  • Può gestire un numero arbitrario di sostituzioni (migliaia o milioni o altro) purché non ti dispiaccia che ci vorrà un po 'più di tempo.

Un'altra opzione sarebbe quella di scrivere quanto sopra come uno sedscript:

s/www\.abcdef/www\.test\.abcdef/g;
s/www\.kmlnop/www\.test\.klmnop/g;
s/aaaa/bbbb/g;
s/cccc/dddd/g;
s/eeee/ffff/g;

È quindi possibile eseguire lo script sul file e tutte le sostituzioni in una volta sola:

sed -f replace.sed infile.txt 

+1 per ,, l'altra opzione ''. Potrebbe essere utile avere le sostituzioni memorizzate in un file! (Spero di ricordarmelo ...)
MPY,

+1 per l '"altra opzione" anche perché utilizza la funzionalità nativa anziché uno script personalizzato, quindi è più portabile / condivisibile
David Cook,

@DavidCook grazie, ma non è più nativo o portatile dell'altro. Il primo approccio sta usando un loop shell POSIX, è esattamente portatile come il secondo. Sarà solo molto più lento poiché utilizza un loop shell.
terdon,

Hai ragione, quello che volevo dire è che il formato del file di script sed è più portabile, perché utilizza la funzionalità incorporata di sed piuttosto che uno script, che dovrebbe essere condiviso insieme al file replments.txt. Tuttavia, sono entrambe ottime opzioni!
David Cook,
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.