Aggiunta di una riga di testo a più file


10

Quindi, ho un sacco di file in una directory e ho bisogno di inserire una riga di testo in ciascuno di essi. Hanno essenzialmente il seguente formato:


<VirtualHost *:80>
        ServerAdmin gabe@localhost
        DocumentRoot /var/www/test1
        ServerName test1.local
        ServerAlias test1
        <Directory "/var/www/test1">
                Options All
                AllowOverride All
        </Directory>
</VirtualHost>

E vorrei inserire una riga prima della chiusura

</ VirtualHost>
etichetta. La mia prima ipotesi è che dovrei essere in grado di farlo con sed, probabilmente abbinando e sostituendo quel tag. Inizierò a provare questo ora, ma se qualcuno ha un modo esistente per farlo, mi piacerebbe ascoltarlo.


Sarò onesto quando dico che penso che questo sia più un compito di programmazione ... e quindi dovrebbe essere su SO. Userei Perl per farlo, specialmente perché scommetto che esiste un modulo perl progettato per analizzare e modificare le configurazioni di Apache.
xenoterracide,

2
Grazie, ma è un compito che dovrebbe essere facile da svolgere con semplici strumenti unix, quindi chiesto qui. Grazie per il tuo commento, però.
gabe.

Risposte:


10

Qualcosa come questo:

sed 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/'

lavori. Se vuoi ripetere questo comando su molti file puoi fare qualcosa del tipo:

for i in *; do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' "$i"; done

Probabilmente migliore (ma non testato) grazie a @ChrisDown:

find . -type f -print0 | while IFS= read -r -d '' filename;\
do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' $filename;\ 
done

fantastico ... questo è proprio quello che stavo cercando.
gabe.

1
Do Non analizzare ls. Usa invece un glob. mywiki.wooledge.org/ParsingLs
Chris Down

Sei rigth @ChrisDown. Per favore, migliora la mia risposta.
lcipriani,

Scegliere un personaggio diverso da quello /per l'espressione sed è più pulito, dal momento che non devi sfuggire alla barra:'s:</VirtualHost>:yourlinehere\n</VirtualHost>:'
Alexander,

2

Se non ti dispiace Perl prova:

perl -pi'*.old' -e 's(</VirtualHost>(Your stuff here\n</VirtualHost>)' myfile

Lo -iswitch salverà il tuo vecchio file con .oldun'estensione e lo stamperà su quello corrente.


2

Puoi anche usare "ex" (riga di comando vi) se la modifica che vuoi fare è anche piuttosto complicata. Ad esempio, si desidera eseguire l'inserimento solo su un'istanza di "".

Uno script di shell come questo può funzionare:

for FILENAME in *.whatever  # Need a criteria to glob, or a list of names
do
    ex -s $FILENAME << END_EDITS
/^<\/VirtualHost>/
O " capital-o, not zero
text to insert goes here
.
w!
q
END_EDITS
done

Questo approccio offre i vantaggi di "ex": trovare una posizione con motivi elaboarte e "movimenti del cursore". Puoi fare cose come trovare un modello, quindi trovare l'istanza successiva, POI fai l'inserto. Oppure puoi cambiare il testo, piuttosto che semplicemente fare inserti. Oppure puoi cambiare tra gli intervalli. Non dimenticare che "ex" ti consente di utilizzare "." come la riga corrente, quindi., / ^ somepatter / s / blah / foo / funzionerà.


0

Puoi utilizzare il seguente codice a riga singola per inserire una o più righe in una determinata posizione in un file, nel tuo caso prima di "VirtualHost". Il codice cerca fondamentalmente il nome del file (potrebbe essere *. *, Se si desidera inserire i testi in tutti i file) all'interno della directory data e delle sue sottodirectory. All'interno dei file trovati, cerca il modello 'VirtualHost'. Dopo aver trovato il modello, lo sostituisce con firstline \ nsecondline \ notherlines \ n \ VirtualHost. Nota che 'VirtualHost' fa parte del testo per la sostituzione, altrimenti lo perderemo.

find directory/ -name filename -print | xargs sed -i 's|VirtualHost|firstline\nsecondline\notherlines\nVirtualHost|g'
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.