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

È stato utile?

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? :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top