Hvordan finder og udskifter du streng uden brugskommandoen Sed?

Som vi alle ved, er sed meget effektiv til at finde og udskifte streng, for eksempel finde “a” og udskift den til “b”: sed "s/a/b/g".

Er det muligt at gøre dette med et andet kommando- eller shell-script i stedet for sed?

Dette er til beskårne linux-systemer til tv, der ikke har kommandoen sed. Så jeg er nødt til at bruge andre kommandoer eller scripts i stedet for sed "s/a/b/g". –

Kommentarer

  • Det er faktisk bare regelmæssigt udtryk baseret erstatning. Ethvert værktøj eller sprog, der er i stand til at håndtere en sådan ting, vil være i stand til at gøre det samme, men med forskellige syntaks: $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. Derudover kan mange værktøjer og sprog også udskifte almindelig tekststreng. Så dit spørgsmål er på en eller anden måde bredt.
  • Hvorfor? Hvilket problem prøver du at løse?
  • Et beskåret linux-system til tv har ikke sed-kommandoen. Så jeg er nødt til at bruge en anden kommando eller et script til i stedet for sed ‘ s / a / b / g ‘.

Svar

Ja, der er forskellige måder at gøre dette på. Du kan bruge awk, perl eller bash til også at udføre disse aktiviteter. Generelt er sed sandsynligvis det mest apropos-værktøj til at udføre denne type opgaver.

Eksempler

Sig, at jeg har disse 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 

Integreret redigering

Ovenstående eksempler kan også direkte ændre filerne. Perl-eksemplet er trivielt. Du skal blot tilføje -i -kontakten.

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

For awk det “er lidt mindre direkte, men lige så effektiv:

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

Denne metode skaber en sub-shell med seler” {…} `hvor filen er omdirigeret til det via dette:

$ { ... } < data.txt 

Når filen er omdirigeret til underskallen, er den slettet og derefter awk køres mod indholdet af filen, der blev læst ind i underskaller STDIN. Dette indhold behandles derefter af awk og skrives tilbage til det samme filnavn som vi lige har slettet, effektivt erstattet det.

Kommentarer

  • Tak for dit svar, og jeg prøver det næste hverdag. Men jeg er ikke sikker på, om det virker, fordi en kommando måske ikke findes i beskårne linux-systemer på tv, såsom ‘ sed ‘. Så jeg vil stadig bruge kommando ‘ find ‘, ‘ grep ‘ og så videre for at løse det.
  • @binghenzq – I ‘ har tilføjet eksempler, der integrerer redigering af filen.
  • -1 Jeg stemte sjældent ned, men i dette tilfælde punktet med spørgsmålet syntes at være en enklere metode snarere end andre mere / lige så komplekse og sandsynligvis også afhængige. Hvis spørgsmålet kun handlede om alternativer til en komplet * nix-maskineinstallation, ville jeg sandsynligvis +1 dette ellers gode svar.
  • @MichaelDurrant – Jeg tilføjede bare de detaljerede integrerede redigeringer b / c OPen bad om dem . Også OP indstillede kravet om IKKE ved hjælp af sed ikke I. Sed er det rigtige værktøj til at foretage udskiftninger som denne, og han ‘ beder naturligvis om bedre at forstå disse værktøjers roller, så det er meget uddannelsesmæssigt at vise nogen disse ting, selvom de er dårlige, til at vise dem hvorfor. Alt for mange gange siger ppl i know bare ” don ‘ t gør det ” uden at forklare hvorfor, så det er jeg også. Men tak for i det mindste at efterlade en kommentar til, hvorfor du DV.
  • Sikker på, jeg syntes, det var et godt svar i alle andre henseender. ja jeg hader -1 uden forklaring.

Svar

Det klassiske alternativ til udskiftning af enkeltbogstaver er tr kommando, der skal være tilgængelig på næsten ethvert system:

$ echo "foobar" | tr a b foobbr 

tr er bedre end sed til dette faktisk siden du bruger sed (endsige perl eller awk) til udskiftning af enkeltbogstaver er som at bruge en forhammer til at dræbe en flue.

grep er ikke designet til dette, det ændrer ikke dets input, det søger kun igennem det.

Alternativt kan du bruge erstatningsfunktioner for nogle skaller. Her ved hjælp af ksh, zsh eller bash syntaks:

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

Vi kunne give dig mere specifikke svar, hvis du forklarede nøjagtigt, hvilket problem du forsøger at løse.

Kommentarer

  • Er der mulighed for at ignorere store og små bogstaver i ${foo//a/b}?
  • @ AlikElzin-kilaka I ‘ er bange ikke. Du ‘ skal bruge noget mere sofistikeret som f.eks. echo "$foo" | sed 's/a/b/i eller give en karakterklasse: echo ${foo//[aA]/b}.

Svar

Du kan bruge POSIX-værktøjet ex:

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

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

Kommentarer

  • stor tak. bare for at tilføje, -c flag er at udføre kommandoen, når redigering begynder (da ex er en editor), og -s flag er enten script-tilstand, der deaktiverer feedback eller som nogle gerne siger slient-mode. ref for mere info: ex-vi.sourceforge.net/ex.html

Svar

Hvis du arbejder med en fil i stedet for en stream, kan du bruge standardteksteditoren, ed:

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

Dette skal være tilgængeligt på enhver * nix. Kommatøjet i ",s/a/b/g" fortæller ed for at arbejde på hver linje (du kan også bruge %, hvilket vil være mere kendt, hvis du tidligere var vim), og resten af det er en standard søgning og erstatning. w beder den skrive (gemme) filen, q beder den om at afslutte.

Bemærk, i modsætning til sed “s -i -indstilling (og lignende indstillinger i andre værktøjer), dette redigerer faktisk filen på stedet i stedet for at snyde med midlertidige filer.

Jeg don “t synes, det er muligt at få dette til at arbejde med streams, men så ved jeg ikke rigtig meget om ed, og jeg ville ikke blive overrasket, hvis det faktisk har den mulighed (unix-filosofien er, hvad den er).

Svar

Brug af forfædren kommando (hvor -s betyder lydløs (lydløs) og kommaet før kommandoerne betyder at udføre på alle linjer):

Bare udskrivning på STDOUT :

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

erstatter stedet:

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

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *