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