Come trovare e sostituire la stringa senza utilizzare il comando Sed?

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

  • In realtà, questo è solo sostituzione basata su espressioni regolari. Qualsiasi strumento o linguaggio in grado di gestire tale operazione sarà in grado di fare lo stesso, ma con varie sintassi: $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.
  • Perché? Quale problema stai cercando di risolvere?
  • Un sistema Linux ritagliato per la TV non ha il comando sed. Quindi devo usare un altro comando o script al posto di sed ‘ s / a / b / g ‘.

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 (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 ! 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *