Cum se găsește și se înlocuiește șirul fără utilizarea comenzii Sed?

După cum știm cu toții, sed este foarte eficient pentru a găsi și a înlocui șirul, de exemplu pentru a găsi „a” și înlocuiți-l cu „b”: sed "s/a/b/g".

Este posibil să faceți acest lucru cu alt script de comandă sau shell în loc de sed?

Aceasta este pentru un sistem linux decupat pentru TV care nu are comanda sed. Așa că trebuie să folosesc alte comenzi sau scripturi în loc de sed "s/a/b/g". –

Comentarii

  • De fapt, adică doar substituirea bazată pe expresia regulată. Orice instrument sau limbaj capabil să gestioneze astfel de lucruri va putea face același lucru, dar cu diverse sintaxi: $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. Pe lângă aceasta, multe instrumente și limbi pot face, de asemenea, înlocuirea șirurilor de text simplu. Deci întrebarea dvs. este cumva largă.
  • De ce? Ce problemă încercați să rezolvați?
  • Un sistem linux decupat pentru TV nu a comandat sed. Așa că trebuie să folosesc altă comandă sau script pentru a în loc de sed ‘ s / a / b / g ‘.

Răspuns

Da, există o varietate de moduri de a face acest lucru. Puteți utiliza awk, perl sau bash pentru a face și aceste activități. În general, deși sed este probabil cel mai adecvat instrument pentru realizarea acestor tipuri de sarcini.

Exemple

Spuneți că am acest exemplu de date, într-un fișier 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 

Editare în linie

Cele de mai sus exemplele pot modifica direct și fișierele. Exemplul Perl este banal. Pur și simplu adăugați comutatorul -i.

$ perl -pie "s/foo/foofoofoo/g" data.txt 

Pentru awk „este puțin mai puțin direct, dar la fel de eficient:

$ { rm data.txt && awk "{gsub("foo", "foofoofoo", $0); print}" > data.txt; } < data.txt 

Această metodă creează un sub-shell cu paranteze” {…} „unde este fișierul redirecționat către acesta prin acest lucru:

$ { ... } < data.txt 

Odată ce fișierul a fost redirecționat în sub-shell, acesta este șters și apoi awk este rulat împotriva conținutului fișierului care a fost citit în sub-shell-urile STDIN. Acest conținut este apoi procesat de awk și redactat în același nume de fișier pe care tocmai l-am șters, înlocuindu-l în mod eficient.

Comentarii

  • Vă mulțumim pentru răspuns și îl voi încerca în ziua lucrătoare următoare. Dar nu sunt sigur dacă funcționează deoarece unele comenzi poate să nu existe într-un sistem linux decupat de televizoare, cum ar fi ‘ sed ‘. comanda ‘ găsiți ‘, ‘ grep ‘ și așa mai departe pentru a o rezolva.
  • @binghenzq – Am ‘ am adăugat exemple care editează fișierul în linie.
  • -1 Rareori vot negativ, dar în acest caz punctul de întrebarea părea a fi mai degrabă o metodă mai simplă decât alta mai complexă / la fel de complexă și probabil, de asemenea, dependentă. Dacă întrebarea ar fi vorba doar despre alternative pentru o instalare completă a mașinii * nix, aș face probabil +1 acest răspuns altfel bun.
  • @MichaelDurrant – Tocmai am adăugat acele editări elaborate în linie b / c OP le-a cerut . De asemenea, OP a setat cerința NOT folosind sed not I. Sed este instrumentul potrivit pentru a face înlocuiri precum acesta și el ‘ solicită în mod evident să înțeleagă mai bine rolurile acestor instrumente, astfel încât să arăți cuiva aceste lucruri, deși sunt rele, sunt extrem de educative în a le arăta de ce. De prea multe ori ppl din cunoștințe spun pur și simplu ” nu ‘ nu o faci ” fără să explic de ce, așa sunt și eu. Dar vă mulțumim că ați lăsat cel puțin un comentariu cu privire la motivele pentru care sunteți DV.
  • Sigur, mi s-a părut un răspuns excelent din toate celelalte aspecte. da, urăsc -1 fără nicio explicație.

Răspuns

Alternativa clasică pentru substituțiile unei singure litere este tr care ar trebui să fie disponibilă pentru aproape orice sistem:

$ echo "foobar" | tr a b foobbr 

tr este mai bun decât sed pentru aceasta, de fapt, de când utilizați sed (să nu mai vorbim perl sau awk) pentru înlocuirea unei singure litere este ca și cum ai folosi un ciocan pentru a ucide o muscă.

grep nu este conceput pentru aceasta, nu își modifică intrarea, ci doar caută prin ea.

Alternativ, puteți utiliza capabilități de substituire ale unor shell-uri. Aici folosind ksh, zsh sau bash sintaxă:

$ foo="foobar" $ echo "${foo//a/b}" foobbr 

Am putea să vă oferim răspunsuri mai specifice dacă ați explica exact ce problemă încercați să rezolvați.

Comentarii

  • Există o opțiune de a ignora majuscule între ${foo//a/b}?
  • @ AlikElzin-kilaka Îmi ‘ mă tem nu. ‘ va trebui să folosiți ceva mai sofisticat, de exemplu: echo "$foo" | sed 's/a/b/i sau să dați o clasă de caractere: echo ${foo//[aA]/b}.

Răspuns

Puteți utiliza instrumentul POSIX ex:

ex a.txt <<eof %s/Sunday/Monday/g xit eof 

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html

Comentarii

  • mulțumiri. doar pentru a adăuga, -c flag este să executați comanda când începe editarea (deoarece ex este un editor) și -s flag este fie modul script care dezactivează feedback-ul, fie așa cum unii doresc să spună modul slient. ref pentru mai multe informații: ex-vi.sourceforge.net/ex.html

Răspuns

Dacă lucrați mai degrabă cu un fișier decât cu un flux, puteți utiliza editorul de text standard, ed:

printf "%s\n" ",s/a/b/g" w q | ed file.txt 

Acest lucru ar trebui să fie disponibil pe orice * nix. Virgula din ",s/a/b/g" spune ed pentru a lucra pe fiecare linie (puteți utiliza și %, care va fi mai familiar dacă sunteți obișnuit cu vim) și restul este o căutare și înlocuire standard. w îi spune să scrie (salva) fișierul, q îi spune să iasă.

Rețineți că, spre deosebire de opțiunea sed „s -i (și opțiuni similare în alte instrumente), aceasta editează de fapt fișierul în loc decât să înșele cu fișiere temporare.

„Nu cred că este posibil să funcționezi cu fluxuri, dar atunci nu știu foarte multe despre ed și nu aș fi surprins dacă de fapt are capacitatea respectivă (filosofia unix fiind ceea ce este).

Răspuns

Folosind strămoșul (în care -s înseamnă liniște (silențios) și virgula înainte ca comenzile să se execute pe toate liniile):

Imprimând doar pe STDOUT :

ed -s file <<! ,s/a/b/g ,p q ! 

înlocuind în loc:

ed -s file <<! ,s/a/b/g w q ! 

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *