Risposte:
sed -i 's/original/new/g' file.txt
Spiegazione:
sed
= Stream EDitor-i
= sul posto (ad es. salvare di nuovo nel file originale)La stringa di comando:
s
= il comando sostitutivooriginal
= un'espressione regolare che descrive la parola da sostituire (o solo la parola stessa)new
= il testo con cui sostituirlog
= globale (ovvero sostituire tutto e non solo la prima occorrenza)file.txt
= il nome del file
sed
, li corrisponderanno. Aggiungi un -r
flag se vuoi usare invece RE estese.
/
personaggio che devi abbinare, puoi semplicemente usare qualche altro personaggio come separatore (es 's_old/text_new/text_g'
.). Altrimenti, puoi mettere un punto \
qualsiasi $ * . [ \ ^
per ottenere il personaggio letterale.
sed -i '.bak' 's/original/new/g' file.txt
può anche essere eseguito con un'estensione di lunghezza zero sed -i '' 's/original/new/g' file.txt
, che non genererà alcun backup.
Esistono diversi modi per farlo. Uno sta usando sed
e Regex. SED è uno Stream Editor per filtrare e trasformare il testo. Un esempio è il seguente:
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog
Un altro modo che può avere più senso di < strin
ed > strout
è con i tubi!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai
The quick brown fox jumped over the lazy sleeping dog
cat
in cat file | sed '...'
non è necessario. Puoi dirlo direttamente sed '...' file
.
sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly
prenderà il file l'anno e farà le 2 modifiche sul posto mentre si esegue un backup. Usando il time bash -c "$COMMAND"
tempo suggerisce che questa versione è ~ 5 volte più veloce.
Ci sono molti modi per raggiungerlo. A seconda della complessità di ciò che si cerca di ottenere con la sostituzione delle stringhe e in base agli strumenti con cui l'utente ha familiarità, alcuni metodi potrebbero essere preferiti più di altri.
In questa risposta sto usando un input.txt
file semplice , che puoi usare per testare tutti gli esempi forniti qui. Il contenuto del file:
roses are red , violets are blue
This is an input.txt and this doesn't rhyme
Bash non è realmente pensato per l'elaborazione del testo, ma semplici sostituzioni possono essere fatte tramite l' espansione dei parametri , in particolare qui possiamo usare una struttura semplice ${parameter/old_string/new_string}
.
#!/bin/bash
while IFS= read -r line
do
case "$line" in
*blue*) printf "%s\n" "${line/blue/azure}" ;;
*) printf "%s\n" "$line" ;;
esac
done < input.txt
Questo piccolo script non esegue la sostituzione sul posto, il che significa che dovresti salvare il nuovo testo in un nuovo file e sbarazzarti del vecchio file, oppure mv new.txt old.txt
Nota a margine: se sei curioso di sapere perché while IFS= read -r ; do ... done < input.txt
viene utilizzato, è fondamentalmente il modo di shell di leggere il file riga per riga. Vedi questo per riferimento.
AWK, essendo un'utilità di elaborazione del testo, è abbastanza appropriato per tale compito. Può fare sostituzioni semplici e molto più avanzate basate su espressioni regolari . Offre due funzioni: sub()
e gsub()
. Il primo sostituisce solo la prima occorrenza, mentre il secondo sostituisce le occorrenze nell'intera stringa. Ad esempio, se abbiamo stringa one potato two potato
, questo sarebbe il risultato:
$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana
$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'
one banana two potato
AWK può prendere un file di input come argomento, quindi fare le stesse cose con input.txt
sarebbe facile:
awk '{sub(/blue/,"azure")}1' input.txt
A seconda della versione di AWK in uso, è possibile che sia presente o meno una modifica sul posto, pertanto la pratica abituale è salvare e sostituire il nuovo testo. Ad esempio qualcosa del genere:
awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt
Sed è un editor di linee. Utilizza anche espressioni regolari, ma per semplici sostituzioni è sufficiente:
sed 's/blue/azure/' input.txt
La cosa positiva di questo strumento è che ha una modifica sul posto, che puoi abilitare con -i
flag.
Perl è un altro strumento che viene spesso utilizzato per l'elaborazione del testo, ma è un linguaggio generico e viene utilizzato in rete, amministrazione di sistema, app desktop e molti altri luoghi. Ha preso in prestito molti concetti / caratteristiche da altri linguaggi come C, sed, awk e altri. La sostituzione semplice può essere effettuata in questo modo:
perl -pe 's/blue/azure/' input.txt
Come sed, perl ha anche la bandiera -i.
Questo linguaggio è molto versatile ed è utilizzato anche in un'ampia varietà di applicazioni. Ha molte funzioni per lavorare con le stringhe, tra le quali è replace()
, quindi se hai variabili simili var="Hello World"
, potresti farlovar.replace("Hello","Good Morning")
Il modo semplice per leggere il file e sostituire la stringa in questo modo sarebbe:
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
Con Python, tuttavia, devi anche eseguire l'output in un nuovo file, cosa che puoi fare anche dallo script stesso. Ad esempio, eccone uno semplice:
#!/usr/bin/env python
import sys
import os
import tempfile
tmp=tempfile.mkstemp()
with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
for line in fd1:
line = line.replace('blue','azure')
fd2.write(line)
os.rename(tmp[1],sys.argv[1])
Questo script deve essere chiamato input.txt
come argomento da riga di comando. Il comando esatto per eseguire lo script Python con l'argomento della riga di comando sarebbe
$ ./myscript.py input.txt
o
$ python ./myscript.py input.txt
Naturalmente, assicurati che ./myscript.py
sia nella tua directory di lavoro corrente e, per la prima volta, assicurati che sia impostato eseguibile conchmod +x ./myscript.py
Python può anche avere espressioni regolari, in particolare c'è un re
modulo, che ha una re.sub()
funzione, che può essere usato per sostituzioni più avanzate.
tr
comando in unix
tr
è un altro ottimo strumento, ma nota che è per sostituire gruppi di caratteri (ad esempio, tr abc cde
si tradurrebbe a
in c
, b
a d
. È un po 'diverso dalla sostituzione di parole intere come con sed
opython
Puoi usare Vim in modalità Ex:
ex -s -c '%s/OLD/NEW/g|x' file
%
seleziona tutte le righe
s
sostituto
g
sostituire tutte le istanze in ciascuna riga
x
scrivere se sono state apportate modifiche (hanno) e uscire
Tramite il comando gsub di awk,
awk '{gsub(/pattern/,"replacement")}' file
Esempio:
awk '{gsub(/1/,"0");}' file
Nell'esempio sopra, tutti gli 1 sono sostituiti da 0 indipendentemente dalla colonna in cui si trova.
Se vuoi fare una sostituzione su una colonna specifica, quindi fai così,
awk '{gsub(/pattern/,"replacement",column_number)}' file
Esempio:
awk '{gsub(/1/,"0",$1);}' file
Sostituisce 1 con 0 solo nella prima colonna.
Attraverso Perl,
$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
inotifywait
under sh
env e riportando i dati in formato CSV (perché il formato personalizzato è difettoso). Ho quindi pensato che non esiste un modo semplice per gestire il documento CSV negli script di shell ... E lo voglio molto leggero. Quindi ho iniziato uno script abbastanza semplice per analizzare e segnalare CSV. Ho letto le specifiche CSV e ho notato che è più elaborato di quanto mi aspettassi e supporta il valore multilinea racchiuso tra virgolette doppie. sed
Facevo affidamento sulla tokenizzazione ma presto mi sono reso conto che anche ciò che sed
chiamano multiline è fino a due righe. Cosa succede se uno dei miei valori CSV si estende su più di due righe?
sed
è il s tream ed itor , in quanto è possibile utilizzare |
(pipe) per inviare flussi standard (STDIN e STDOUT in particolare) attraverso sed
e modificare a livello di codice al volo, che lo rende uno strumento utile nella tradizione filosofia Unix; ma può anche modificare direttamente i file, usando il -i
parametro menzionato di seguito.
Considera quanto segue :
sed -i -e 's/few/asd/g' hello.txt
s/
è usato per s ubstitute l'espressione trovata few
con asd
:
I pochi, i coraggiosi.
Il asd, il coraggioso.
/g
sta per "globale", che significa farlo per l'intera linea. Se si interrompe il /g
(con s/few/asd/
, ci devono sempre essere tre barre a prescindere) e few
appare due volte sulla stessa linea, solo la prima few
viene cambiata in asd
:
I pochi uomini, le poche donne, i coraggiosi.
Gli uomini asd, le poche donne, i coraggiosi.
Ciò è utile in alcune circostanze, come la modifica di caratteri speciali all'inizio delle righe (ad esempio, la sostituzione dei simboli maggiore di quelli che alcune persone usano per citare il materiale precedente nei thread di posta elettronica con una scheda orizzontale lasciando una disuguaglianza algebrica citata più avanti nella riga intatto), ma nel tuo esempio in cui specifichi che dovunque si few
verifichi dovrebbe essere sostituito, assicurati di averlo /g
.
Le seguenti due opzioni (flag) sono combinate in una sola -ie
:
-i
opzione viene utilizzata per modificare i n immettere sul file hello.txt
.
-e
opzione indica la posta Xpression / comando da eseguire, in questo caso s/
.
Nota: è importante utilizzare -i -e
per cercare / sostituire. In tal caso -ie
, si crea un backup di ogni file con la lettera 'e' allegata.
Puoi fare così:
locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g"
Esempi: per sostituire tutte le occorrenze [logdir ',' '] (senza []) con [logdir', os.getcwd ()] in tutti i file risultanti dal comando di individuazione, eseguire:
EX1:
locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"
EX2:
locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"
dove [tensorboard / program.py] è il file da cercare
logdir', ''
-> /logdir', os.getcwd()
) rende questa risposta difficile da analizzare. Inoltre, vale la pena specificare che la tua risposta individua prima i file su cui utilizzare sed, perché non fa parte della domanda.