Hoe string te vinden en te vervangen zonder het commando Sed te gebruiken?

Zoals we allemaal weten, sed is zeer efficiënt om een string te vinden en te vervangen, bijvoorbeeld “a” en vervang het door “b”: sed "s/a/b/g".

Is het mogelijk om dit te doen met een ander commando of shellscript in plaats van sed?

Dit is voor een bijgesneden Linux-systeem voor tv dat het sed commando niet heeft. Dus ik moet andere commandos of scripts gebruiken in plaats van sed "s/a/b/g". –

Opmerkingen

  • Eigenlijk is dat alleen op reguliere expressie gebaseerde substitutie. Elke tool of taal die zoiets aankan, kan hetzelfde doen, maar met verschillende syntaxis: $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. Daarnaast kunnen veel tools en talen ook tekenreeksen in gewone tekst vervangen. Dus uw vraag is enigszins breed.
  • Waarom? Welk probleem probeer je op te lossen?
  • Een bijgesneden Linux-systeem voor tv heeft geen sed-commando. Dus ik moet een ander commando of script gebruiken in plaats van sed ‘ s / a / b / g ‘.

Answer

Ja, er zijn verschillende manieren om dit te doen. U kunt awk, perl of bash ook gebruiken om deze activiteiten uit te voeren. In het algemeen is sed waarschijnlijk de meest geschikte tool om dit soort taken uit te voeren.

Voorbeelden

Stel dat ik deze voorbeeldgegevens heb, in een bestand 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 

Inline bewerken

Het bovenstaande voorbeelden kunnen de bestanden ook direct wijzigen. Het Perl-voorbeeld is triviaal. Voeg gewoon de -i schakelaar toe.

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

Voor awk “sa iets minder direct maar net zo effectief:

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

Deze methode maakt een subshell met de accolades” {…} `waar het bestand is hiernaar doorgestuurd:

$ { ... } < data.txt 

Zodra het bestand is omgeleid naar de subshell, wordt het verwijderd en vervolgens awk wordt uitgevoerd tegen de inhoud van het bestand dat is ingelezen in de subshells STDIN. Deze inhoud wordt vervolgens verwerkt door awk en teruggeschreven naar dezelfde bestandsnaam die we zojuist hebben verwijderd, waardoor het effectief is vervangen.

Opmerkingen

  • Bedankt voor je antwoord en ik zal het de volgende werkdag proberen. Maar ik weet niet zeker of het werkt omdat een commando misschien niet bestaat in een bijgesneden Linux-systeem van tv, zoals ‘ sed ‘. Dus ik wil nog steeds gebruiken commando ‘ vind ‘, ‘ grep ‘ enzovoort om het op te lossen.
  • @binghenzq – Ik ‘ heb voorbeelden toegevoegd die het bestand inline bewerken.
  • -1 Ik stem zelden omlaag, maar in dit geval is het punt van de vraag leek eerder een eenvoudigere methode dan andere, meer / even complexe en waarschijnlijk ook afhankelijke. Als de vraag alleen ging over alternatieven voor een volledige * nix-machine-installatie, zou ik dit anders goede antwoord waarschijnlijk een +1 geven.
  • @MichaelDurrant – Ik heb zojuist die uitgebreide inline bewerkingen toegevoegd, omdat het OP erom vroeg . Ook stelde het OP de vereiste van NOT in met sed niet I. Sed is de juiste tool voor het uitvoeren van substituties zoals deze, en hij ‘ s die duidelijk vragen om de rollen van deze tools beter te begrijpen, dus iemand deze dingen laten zien, hoewel slecht, zijn buitengewoon leerzaam in het laten zien waarom. Te vaak zeggen de mensen die het kennen, gewoon ” niet ‘ doen ” zonder uit te leggen waarom, dus ik ben. Maar bedankt dat je op zijn minst een opmerking hebt achtergelaten over waarom je DV bent.
  • Zeker, ik dacht dat het in alle andere opzichten een geweldig antwoord was. ja ik haat -1 zonder uitleg.

Antwoord

Het klassieke alternatief voor vervangingen van één letter is de tr commando dat op vrijwel elk systeem beschikbaar zou moeten zijn:

$ echo "foobar" | tr a b foobbr 

tr is hiervoor eigenlijk beter dan sed, aangezien sed (laat staan perl of awk) voor vervangingen van één letter is als het gebruik van een voorhamer om een vlieg te doden.

grep is hier niet voor ontworpen, het wijzigt zijn invoer niet, het zoekt er alleen doorheen.

Als alternatief kunt u de vervangingsmogelijkheden van sommige shells gebruiken. Hier met behulp van ksh, zsh of bash syntaxis:

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

We zouden u meer specifieke antwoorden kunnen geven als u precies heeft uitgelegd welk probleem u probeert op te lossen.

Opmerkingen

  • Is er een optie om hoofdlettergebruik te negeren in ${foo//a/b}?
  • @ AlikElzin-kilaka Ik ‘ ben bang niet. U ‘ zult iets geavanceerder moeten gebruiken, bijvoorbeeld: echo "$foo" | sed 's/a/b/i of een tekenklasse geven: echo ${foo//[aA]/b}.

Antwoord

U kunt de POSIX-tool gebruiken ex:

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

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

Reacties

  • hartelijk dank. gewoon om toe te voegen, -c vlag is om het commando uit te voeren wanneer het bewerken begint (aangezien ex een editor is) en -s vlag is ofwel scriptmodus die feedback uitschakelt of zoals sommigen zeggen slient-modus. ref voor meer info: ex-vi.sourceforge.net/ex.html

Antwoord

Als je met een bestand werkt in plaats van met een stream, kun je de standaard teksteditor gebruiken, ed:

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

Dit zou beschikbaar moeten zijn op elke * nix. De komma in ",s/a/b/g" vertelt ed om op elke regel te werken (je kunt ook % gebruiken, wat meer vertrouwd zal zijn als je “gewend bent aan vim”, en de rest daarvan is een standaard zoeken en vervangen. w vertelt het om het bestand te schrijven (op te slaan), q vertelt het om af te sluiten.

Merk op dat, in tegenstelling tot sed “s -i optie (en vergelijkbare opties in andere tools), dit bewerkt het bestand eigenlijk op zijn plaats in plaats van vals te spelen met tijdelijke bestanden.

Ik don “Ik denk niet dat het mogelijk is om dit met streams te laten werken, maar dan weet ik” niet echt veel over ed en het zou me niet verbazen als het die mogelijkheid wel heeft (de Unix-filosofie is wat het is).

Antwoord

De voorouder gebruiken commando (waarin -s stil (stil) betekent en de komma voor de commandos betekent uitvoeren op alle regels):

Gewoon afdrukken op STDOUT :

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

ter plaatse vervangen:

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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *