Som vi alla vet är sed
mycket effektivt för att hitta och ersätta sträng, till exempel hitta ”a” och ersätt den till ”b”: sed "s/a/b/g"
.
Är det möjligt att göra detta med ett annat kommando eller skalskript istället för sed
?
Detta är för beskurna Linux-system för TV som inte har kommandot sed
. Så jag måste använda andra kommandon eller skript istället för sed "s/a/b/g". –
Kommentarer
Svar
Ja, det finns många olika sätt att göra detta. Du kan använda awk
, perl
eller bash
för att göra dessa aktiviteter också. I allmänhet är sed
förmodligen det mest aproposverktyget för att utföra dessa typer av uppgifter.
Exempel
Säg att jag har denna exempeldata, 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
Inline redigering
Ovanstående exempel kan också direkt ändra filerna. Perl-exemplet är trivialt. Lägg bara till omkopplaren -i
.
$ perl -pie "s/foo/foofoofoo/g" data.txt
För awk
ӊr lite mindre direkt men lika effektivt:
$ { rm data.txt && awk "{gsub("foo", "foofoofoo", $0); print}" > data.txt; } < data.txt
Den här metoden skapar ett underskal med hängslen” {…} `där filen är omdirigeras till den via detta:
$ { ... } < data.txt
När filen har omdirigerats till underskalet raderas den och sedan awk
körs mot innehållet i filen som har lästs in i underskal STDIN. Detta innehåll bearbetas sedan av awk
och skrivs tillbaka till samma filnamn som vi precis har tagit bort, effektivt ersatt det.
Kommentarer
- Tack för att du svarar och jag kommer att prova nästa arbetsdag.Men jag är inte säker på om det fungerar eftersom vissa kommandon kanske inte existerar i beskurna Linux-system på TV, som ’ sed ’. Så jag vill fortfarande använda kommando ’ hitta ’, ’ grep ’ och så vidare för att lösa det.
- @binghenzq – Jag ’ har lagt till exempel som inline redigerar filen.
- -1 Jag röstade sällan men i det här fallet poängen med frågan verkade vara en enklare metod snarare än andra mer / lika komplexa och sannolikt också beroende. Om frågan bara handlade om alternativ för en fullständig * nix-maskininstallation skulle jag antagligen +1 detta annars bra svar.
- @MichaelDurrant – Jag lade bara till de detaljerade inline-redigeringarna b / c OP frågade efter dem . Även OP ställde kravet på INTE med
sed
inte I. Sed är det lämpliga verktyget för att utbyta sådana som detta, och han ’ ber uppenbarligen att bättre förstå rollen för dessa verktyg, så att visa någon dessa saker men dåliga, är extremt utbildning för att visa dem varför. För många gånger säger ppl i vet helt enkelt ” don ’ t gör det ” utan att förklara varför, så jag är det. Men tack för att du åtminstone lämnade en kommentar till varför du DV. - Visst, jag tyckte att det var ett bra svar i alla andra avseenden. ja jag hatar -1 utan förklaring.
Svar
Det klassiska alternativet för enstaka bokstavsbyten är tr
kommando som borde finnas tillgängligt i nästan vilket system som helst:
$ echo "foobar" | tr a b foobbr
tr
är bättre än sed
för detta faktiskt eftersom du använder sed
(än mindre perl
eller awk
) för substitutioner med en bokstav är som att använda en slägga för att döda en fluga.
grep
är inte utformad för detta, den ändrar inte sin ingång, den söker bara igenom den.
Alternativt kan du använda ersättningsmöjligheter för vissa skal. Här använder du ksh
, zsh
eller bash
syntax:
$ foo="foobar" $ echo "${foo//a/b}" foobbr
Vi kan ge dig mer specifika svar om du förklarar exakt vilket problem du försöker lösa.
Kommentarer
- Finns det ett alternativ att ignorera fall i
${foo//a/b}
? - @ AlikElzin-kilaka I ’ är rädd inte. Du ’ måste använda något mer sofistikerat som till exempel:
echo "$foo" | sed 's/a/b/i
eller ge en karaktärsklass:echo ${foo//[aA]/b}
.
Svar
Du kan använda POSIX-verktyget ex
:
ex a.txt <<eof %s/Sunday/Monday/g xit eof
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
Kommentarer
- stort tack. bara för att lägga till, -c-flaggan är att utföra kommandot när redigeringen börjar (eftersom ex är en redaktör) och -s-flaggan är antingen skriptläge som inaktiverar feedback eller som vissa vill säga slient-mode. ref för mer info: ex-vi.sourceforge.net/ex.html
Svar
Om du arbetar med en fil snarare än en ström kan du använda standardtextredigeraren, ed
:
printf "%s\n" ",s/a/b/g" w q | ed file.txt
Detta ska vara tillgängligt på valfri * nix. Kommatecken i ",s/a/b/g"
säger till ed
för att arbeta på varje rad (du kan också använda %
, vilket kommer att vara mer bekant om du brukade vim), och resten av det är en standard sökning och ersättning. w
säger att den ska skriva (spara) filen, q
säger att den ska avslutas.
Observera att, till skillnad från sed ”s -i
-alternativ (och liknande alternativ i andra verktyg), detta redigerar faktiskt filen på plats snarare än fusk med tillfälliga filer.
Jag don ”t tror att det är möjligt att få detta att fungera med strömmar, men då vet jag inte riktigt mycket om ed
och jag skulle inte bli förvånad om det faktiskt har den förmågan (unix-filosofin är vad det är).
Svar
Använda förfadern ed kommando (där -s
betyder tyst (tyst) och kommatecken före kommandona betyder att köra på alla rader):
Bara att skriva ut på STDOUT :
ed -s file <<! ,s/a/b/g ,p q !
ersätter på plats:
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
. Utöver det kan många verktyg och språk också byta ut textsträngar. Så din fråga är på något sätt bred.