Come sostituire il contenuto tra due pattern dal file?


9

Ho il seguente formato del file:

<common>
fitnes=0
genetic=1
method=0
</common>
<inputs>
foo=bar
bar=foo
</inputs>
<limits>
balance=200.00
</limits>

e vorrei eliminare tutto ciò che sta tra <inputs>e </inputs>(escluso lo schema stesso) e sostituirlo con il contenuto di un altro file (ad es foo.txt.). In altre parole, si allinea con foo=bare bar=fooverrebbe sostituito con un altro contenuto.

Probabilmente può essere simile a come elimini una corrispondenza su più righe , come:

:g/<inputs/,/inputs>/d

ma non sono sicuro di cosa dovrei sostituire dper inserire il contenuto di un altro file, ma voglio mantenere il modello di corrispondenza.

Un approccio simile sarebbe rimuovere il contenuto interno del tag html , come

:/<inputs>/norm vitd

ma poi non so come aggiungeresti il ​​contenuto del file.

Idealmente sto cercando di trovare una copertina, dal momento che farà parte di un'altra sceneggiatura.

Come posso raggiungerlo?

Risposte:


10

Una sostituzione può essere utilizzata per sostituire un modello con il risultato di un'espressione come questa:

:keeppatterns %s;<inputs>\zs\_.\{-}\ze</inputs>;\=insert(readfile('test.txt'), '')

Vedere :help sub-replace-expression

Si noti che keeppatternsimpedisce al substitutecomando di aggiungere qualcosa alla cronologia delle ricerche e conserva l '"ultimo registro del modello di ricerca" - vedere :help "/. E 'buona norma impedire l'esecuzione da inutilmente modificare lo stato globale di Vim con i modificatori di comando keepalt, keepjumps, lockmarks, keepmarks, e keeppatterns.


5

Un approccio alternativo a quello di Gary è questo:

:g/^<inputs>/+,/^<\/inputs>/-d|-r dummy

Che prima cancella tutto nel modello dato, che utilizza il :rcomando per leggere i dati dal file fittizio. Ora, se hai bisogno di estrarre il nome del file dalle linee tra il <input>/</input>modello, diventa un po 'più complicato.


4

Questo sembra funzionare, almeno su un sistema Unix:

:/<inputs>/+1,/<\/inputs>/-1!cat foo.txt

Usa il {range}!{filter}comando per filtrare le righe da una dopo <inputs>l'altra </inputs>attraverso il programma esterno cat foo.txt. In questo caso, catignora il suo input standard, quindi le righe originali vengono eliminate e sostituite dal contenuto del file foo.txt.

Vedere:

:help :range!
:help cmdline-ranges

2

Sento che una macro sarà un approccio più semplice. Soprattutto se hai diversi posti per fare lo stesso.

  1. Tieni aperti solo quei 2 file.
  2. Ora nel primo file inizia a registrare per qa,( aè il nome del record).
  3. Cercare il motivo iniziale, premere verso il basso , quindi premere Ctrl- v, cercare il motivo finale, premere verso l'alto . Ora è selezionata la parte che si desidera eliminare. Cancellalo.
  4. Contrassegnare la posizione utilizzando ma( aè il nome del segno) e salvare il file.
  5. Vai al 2 ° file, per :b2comando e allo stesso modo seleziona la parte secondo i tuoi criteri di inizio / fine.
  6. Torna a questo file premi aper andare a quel punto. Incolla lì p.
  7. Cerca di nuovo i criteri di fine e attraversa la sezione per non colpirla di nuovo.
  8. Terminare la ricodifica premendo q.
  9. Ripeti il ​​numero di volte entro 40@a.

1
Grazie per il suggerimento, va bene, ma non aiuterà in questo caso particolare, poiché sto cercando una soluzione non interattiva come parte dello exscript in cui posso specificare quale file inserire a seconda degli argomenti di input dell'utente.
Kenorb,

1

Se questo è un altro tentativo di analizzare XML con strumenti non XML, non farlo.

Le soluzioni qui sono valide, ma l'intenzione potrebbe non esserlo. Se l'XML non proviene da una fonte ben domata, nel tag potrebbero essere presenti escape, CDATA o spazi bianchi!

Quindi xsltproc dal comando in vi può farcela.


Il file non è in realtà un formato XML corretto, ma in realtà non è un inifile ben documentato con quei 3 tag simili a XML.
Kenorb,
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.