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