Come modificare il formato delle variabili di sostituzione in un modello
-
04-07-2019 - |
Domanda
Devo scorrere i file in una directory ed eseguire la sostituzione seguente.
Prima:
Ciao $ {USER_NAME}, vivi a $ {} HOME_ADDRESS. Ora è $ {TIME}
Dopo:
Ciao $ {userName}, abiti a $ {} HomeAddress. Ora è $ {time}
Il numero di token diversi che appaiono all'interno di $ {} è elevato, quindi non è davvero possibile eseguirlo:
find . -name '*' -exec sed -i 's/${USER_NAME}/${userName}/g' {} \;
find . -name '*' -exec sed -i 's/${TIME}/${time}/g' {} \;
ecc.
Spero che sia possibile eseguire questa sostituzione usando un singolo comando, simile a:
find . -name '*' -exec sed 's/XXX/YYY/g' {} \;
Ma non riesco a capire cosa sostituire a XXX e YYY. È possibile farlo in un solo comando?
Saluti, Donal
Soluzione
Il flag -i
su sed modificherà un file sul posto. Per XXX e YYY, useresti qualcosa del tipo:
sed -i 's/USER_NAME/userName/g'
e così via.
Aggiornamento: vedo che la tua domanda riguardava davvero la modifica di " USER_NAME " in " userName " automaticamente. Puoi provare questo script Perl:
sub convert {
my $r = lc Il flag -i
su sed modificherà un file sul posto. Per XXX e YYY, useresti qualcosa del tipo:
sed -i 's/USER_NAME/userName/g'
e così via.
Aggiornamento: vedo che la tua domanda riguardava davvero la modifica di " USER_NAME " in " userName " automaticamente. Puoi provare questo script Perl:
perl -i convert.pl inputfile.txt
Eseguilo in questo modo:
$ cat inputfile.txt
Hello ${USER_NAME}, you live at ${HOME_ADDRESS}. It is now ${TIME}
$ perl -i convert.pl inputfile.txt
$ cat inputfile.txt
Hello ${userName}, you live at ${homeAddress}. It is now ${time}
Output di esempio:
<*>[0];
$r =~ s/_(.)/\U$1\E/g;
return $r;
}
while (<>) {
s/\${([A-Z_]+)}/\${@{[convert $1]}}/g;
print;
}
Eseguilo in questo modo:
<*>Output di esempio:
<*>Altri suggerimenti
Formattato per chiarezza:
sed -i '/^Hello/ { s/\$\{USER_NAME\}/\$\{userName\}/g
s/\$\{HOME_ADDRESS\}/\$\{homeAddress\}/g
s/\$\{TIME\}/\$\{time\}/g
}'
Dove / ^ Hello /
identifica le linee su cui si desidera agire (renderlo più specifico se necessario) e il resto sostituisce il nome di ogni variabile.
Se stai scrivendo questo in uno script, considera l'uso di un documento HERE per mantenere la formattazione e facilitare la lettura e l'aggiornamento ...
La risposta sopra funziona davvero bene. Per completezza, potrei aggiungere che puoi fare:
sed '/^Hello/ { s/\$\{USER_NAME\}/\$\{userName\}/g' <filename> \
| sed 's/\$\{HOME_ADDRESS\}/\$\{homeAddress\}/g' \
| sed 's/\$\{TIME\}/\$\{time\}/g'
Sono funzionalmente identici (tranne che il mio dump a stdout; dovrai metterlo da qualche parte (ma riesci a conservare l'originale nel caso in cui, come e, rovini regolarmente le tue regexps). formulazione solo perché posso iniziare con il comando one sed, quindi aggiungere altro con
!! | sed 'yet-enother-regexp'
Tasti freccia? vi-mode? Chi ha bisogno di quella roba? :)