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
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 ed (î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 !
$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ă.