Come tutti sappiamo, sed
è molto efficiente per trovare e sostituire stringhe, ad esempio find “a” e sostituiscilo con “b”: sed "s/a/b/g"
.
È possibile farlo con un altro comando o script di shell invece di sed
?
Questo è per un sistema Linux ritagliato per TV che non ha il comando sed
. Quindi devo usare altri comandi o script invece di sed "s/a/b/g". –
Commenti
Risposta
Sì, ci sono molti modi per farlo. Puoi utilizzare awk
, perl
o bash
per svolgere anche queste attività. In generale, anche se sed
è probabilmente lo strumento più adatto per svolgere questo tipo di attività.
Esempi
Supponiamo che io disponga di questi dati di esempio, in un file data.txt
:
foo bar 12,300.50 foo bar 2,300.50 abc xyz 1,22,300.50
awk
$ awk "{gsub("foo", "foofoofoo", $0); print}" data.txt foofoofoo bar 12,300.50 foofoofoo bar 2,300.50 abc xyz 1,22,300.50
Perl
$ perl -pe "s/foo/foofoofoo/g" data.txt foofoofoo bar 12,300.50 foofoofoo bar 2,300.50 abc xyz 1,22,300.50
Modifica in linea
Quanto sopra anche gli esempi possono modificare direttamente i file. Lesempio di Perl è banale. Aggiungi semplicemente lopzione -i
.
$ perl -pie "s/foo/foofoofoo/g" data.txt
Per awk
“è un po meno diretto ma altrettanto efficace:
$ { rm data.txt && awk "{gsub("foo", "foofoofoo", $0); print}" > data.txt; } < data.txt
Questo metodo crea una sotto-shell con le parentesi graffe” {…} “dove si trova il file reindirizzato in esso tramite questo:
$ { ... } < data.txt
Una volta che il file è stato reindirizzato nella sub-shell, viene eliminato e quindi awk
viene eseguito sul contenuto del file che è stato letto nelle sotto shell STDIN. Questo contenuto viene quindi elaborato da awk
e riscritto con lo stesso nome file che abbiamo appena eliminato, sostituendolo di fatto.
Commenti
- Grazie per la tua risposta e proverò il prossimo giorno lavorativo. Ma non sono sicuro se funziona perché alcuni comandi potrebbero non esistere in un sistema televisivo Linux ritagliato, come ‘ sed ‘. Quindi voglio ancora usarlo comando ‘ trova ‘, ‘ grep ‘ e così via per risolverlo.
- @binghenzq – Ho ‘ aggiunto esempi che modificano il file in linea.
- -1 Raramente ho un voto negativo, ma in questo caso il punto di la domanda sembrava essere un metodo più semplice piuttosto che altri più / ugualmente complessi e probabilmente anche dipendenti. Se la domanda riguardasse solo le alternative per uninstallazione completa su una macchina * nix, probabilmente farei +1 su questa risposta altrimenti buona.
- @MichaelDurrant – Ho appena aggiunto quelle elaborate modifiche in linea b / c che lOP ha chiesto per loro . Inoltre lOP ha stabilito il requisito di NON utilizzare
sed
non I. Sed è lo strumento appropriato per fare sostituzioni come questa, e ‘ sta ovviamente chiedendo di capire meglio il ruolo di questi strumenti, quindi mostrare a qualcuno queste cose sebbene cattive, è estremamente istruttivo nel mostrare loro il perché. Troppe volte le persone che sanno dire semplicemente ” don ‘ non farlo ” senza spiegare perché, così sono. Ma grazie almeno per aver lasciato un commento sul perché tu DV. - Certo, ho pensato che fosse unottima risposta sotto tutti gli altri aspetti. sì, odio -1 senza alcuna spiegazione.
Risposta
Lalternativa classica per la sostituzione di una singola lettera è la tr
che dovrebbe essere disponibile su quasi tutti i sistemi:
$ echo "foobar" | tr a b foobbr
tr
è meglio di sed
per questo in realtà poiché utilizza sed
(figuriamoci perl
o awk
) per la sostituzione di una sola lettera è come usare una mazza per uccidere una mosca.
grep
non è progettato per questo, non modifica il suo input, cerca solo attraverso di esso.
In alternativa, puoi usare le capacità di sostituzione di alcune shell. Qui utilizzando la sintassi ksh
, zsh
o bash
:
$ foo="foobar" $ echo "${foo//a/b}" foobbr
Potremmo darti risposte più specifiche se spiegassi esattamente quale problema stai cercando di risolvere.
Commenti
- Esiste unopzione per ignorare le maiuscole / minuscole in
${foo//a/b}
? - @ AlikElzin-kilaka I ‘ ho paura non. ‘ dovrai utilizzare qualcosa di più sofisticato come, ad esempio:
echo "$foo" | sed 's/a/b/i
o fornire una classe di caratteri:echo ${foo//[aA]/b}
.
Risposta
Puoi utilizzare lo strumento POSIX ex
:
ex a.txt <<eof %s/Sunday/Monday/g xit eof
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
Commenti
- grazie mille. solo per aggiungere, il flag -c è quello di eseguire il comando quando inizia la modifica (poiché ex è un editor) e il flag -s è in modalità script che disabilita il feedback o, come alcuni amano dire slient-mode. rif per maggiori informazioni: ex-vi.sourceforge.net/ex.html
Risposta
Se stai lavorando con un file anziché con uno stream, puoi utilizzare leditor di testo standard, ed
:
printf "%s\n" ",s/a/b/g" w q | ed file.txt
Dovrebbe essere disponibile su qualsiasi * nix. La virgola in ",s/a/b/g"
indica ed
per lavorare su ogni riga (puoi anche usare %
, che sarà più familiare se “sei abituato a vim), e il resto di esso è una ricerca e sostituzione standard. w
gli dice di scrivere (salva) il file, q
gli dice di uscire.
Nota che, a differenza di sed “s -i
(e opzioni simili in altri strumenti), questo in realtà modifica il file sul posto piuttosto che barare con i file temporanei.
Io non “Non penso sia possibile farlo funzionare con gli stream, ma in realtà non so molto di ed
e non sarei sorpreso se avesse effettivamente quella capacità (la filosofia unix è quello che è).
Rispondi
Utilizzando lantenato ed (in cui -s
significa silenzioso (silenzioso) e la virgola prima dei comandi significa esecuzione su tutte le righe):
Solo stampa su STDOUT :
ed -s file <<! ,s/a/b/g ,p q !
in sostituzione sul posto:
ed -s file <<! ,s/a/b/g w q !
$var=~s/a/b/g
,gsub(/a/,"b",var)
,var.gsub(/a/,'b')
,var.replace(/a/g,'b')
,preg_replace("/a/","b",$var)
,regsub -all a b $var
. Inoltre, molti strumenti e lingue possono anche sostituire le stringhe di testo semplice. Quindi la tua domanda è in qualche modo ampia.