Hvordan finne og erstatte streng uten brukskommandoen Sed?

Som vi alle vet, er sed veldig effektivt å finne og erstatte streng, for eksempel å finne «a» og erstatt den til «b»: sed "s/a/b/g".

Er det mulig å gjøre dette med et annet kommando eller skallskript i stedet for sed?

Dette er for beskjærte linux-systemer for TV som ikke har sed -kommandoen. Så jeg må bruke andre kommandoer eller skript i stedet for sed "s/a/b/g". –

Kommentarer

  • Egentlig, det vil si bare vanlig uttrykk basert erstatning. Ethvert verktøy eller språk som er i stand til å håndtere slike ting, vil kunne gjøre det samme, men med forskjellige syntakser: $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. I tillegg til det kan mange verktøy og språk også erstatte streng tekststreng. Så spørsmålet ditt er på en eller annen måte bredt.
  • Hvorfor? Hvilket problem prøver du å løse?
  • Et beskåret Linux-system for TV har ikke sed-kommandoen. Så jeg må bruke annen kommando eller skript til i stedet for sed ' s / a / b / g '.

Svar

Ja, det finnes en rekke måter å gjøre dette på. Du kan bruke awk, perl eller bash til å gjøre disse aktivitetene også. Generelt sett er sed sannsynligvis det mest nyttige verktøyet for å utføre denne typen oppgaver.

Eksempler

Si at jeg har denne eksempeldata, i en fil 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 

Integrert redigering

Ovenstående eksempler kan også direkte endre filene. Perl-eksemplet er trivielt. Bare legg til -i -bryteren.

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

For awk «er litt mindre direkte, men like effektiv:

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

Denne metoden oppretter et underskall med seler» {…} `der filen er omdirigert til den via dette:

$ { ... } < data.txt 

Når filen er omdirigert til underskallet, blir den slettet og deretter awk kjøres mot innholdet i filen som ble lest inn i underskjellene STDIN. Dette innholdet blir deretter behandlet av awk og skrevet tilbake til samme filnavn som vi nettopp har slettet, effektivt erstattet det.

Kommentarer

  • Takk for svaret ditt, og jeg vil prøve det neste virkedag.Men jeg er ikke sikker på om det fungerer fordi noen kommandoer kanskje ikke eksisterer i beskjærte Linux-systemer på TV, for eksempel ' sed '. Så jeg vil fortsatt bruke kommando ' finn ', ' grep ' og så videre for å løse det.
  • @binghenzq – Jeg ' har lagt til eksempler som innebærer redigering av filen.
  • -1 Jeg stemte sjelden, men i dette tilfellet poenget med spørsmålet syntes å være en enklere metode i stedet for andre mer / like komplekse og sannsynligvis også avhengige. Hvis spørsmålet bare handlet om alternativer for en full * nix-maskininstallasjon, ville jeg sannsynligvis +1 dette ellers gode svaret.
  • @MichaelDurrant – Jeg la bare til de forseggjorte innebygde redigeringene b / c OPEN ba om dem . Også OP satte kravet om IKKE å bruke sed ikke I. Sed er det riktige verktøyet for å gjøre erstatninger som dette, og han ' ber tydeligvis om å bedre forstå rollene til disse verktøyene, så det å vise noen disse tingene, selv om de er dårlige, er ekstremt lærerikt å vise dem hvorfor. For mange ganger sier bare ppl i vet bare " don ' t gjør det " uten å forklare hvorfor, så det er jeg. Men takk for at du i det minste la igjen en kommentar til hvorfor du DV.
  • Jada, jeg syntes det var et flott svar i alle andre henseender. ja jeg hater -1 uten forklaring.

Svar

Det klassiske alternativet for substitusjoner med en bokstav er tr kommando som skal være tilgjengelig på omtrent hvilket som helst system:

$ echo "foobar" | tr a b foobbr 

tr er bedre enn sed for dette faktisk siden du bruker sed (enn si perl eller awk) for substitusjoner med en bokstav er som å bruke en slegge for å drepe en flue.

grep er ikke designet for dette, den endrer ikke inngangen, den søker bare gjennom den.

Alternativt kan du bruke erstatningsfunksjonene for noen skjell. Her bruker du ksh, zsh eller bash syntaks:

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

Vi kan gi deg mer spesifikke svar hvis du forklarer nøyaktig hvilket problem du prøver å løse.

Kommentarer

  • Er det et alternativ å ignorere store og små bokstaver i ${foo//a/b}?
  • @ AlikElzin-kilaka I ' er redd ikke. Du ' du må bruke noe mer sofistikert som for eksempel: echo "$foo" | sed 's/a/b/i eller gi en karakterklasse: echo ${foo//[aA]/b}.

Svar

Du kan bruke POSIX-verktøyet ex:

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

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

Kommentarer

  • stor takk. bare for å legge til, -c flagg er å utføre kommandoen når redigering begynner (siden ex er redaktør) og -s flagg er enten skriptmodus som deaktiverer tilbakemelding eller som noen vil si slient-mode. ref for mer info: ex-vi.sourceforge.net/ex.html

Svar

Hvis du jobber med en fil i stedet for en strøm, kan du bruke standard tekstredigeringsprogram, ed:

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

Dette skal være tilgjengelig på hvilken som helst * nix. Kommaet i ",s/a/b/g" forteller ed for å jobbe på hver linje (du kan også bruke %, noe som vil være mer kjent hvis du vant til å vim), og resten av det er et standard søk og erstat. w ber den skrive (lagre) filen, q ber den avslutte.

Merk at, i motsetning til sed «s -i alternativ (og lignende alternativer i andre verktøy), dette redigerer faktisk filen på stedet i stedet for juks med midlertidige filer.

Jeg don «t tror det er mulig å få dette til å fungere med strømmer, men da vet jeg ikke veldig mye om ed, og jeg vil ikke bli overrasket om den faktisk har den muligheten (Unix-filosofien er hva den er).

Svar

Bruk av forfedren -kommando (der -s betyr stille (lydløs) og kommaet før kommandoene betyr å utføre på alle linjer):

Bare utskrift på STDOUT :

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

erstatter på stedet:

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

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *