Jak všichni víme, sed
je velmi efektivní najít a nahradit řetězec, například najít „a“ a nahraďte jej „b“: sed "s/a/b/g"
.
Je to možné pomocí jiného příkazového nebo shell skriptu místo sed
?
Toto je pro oříznuté linuxové systémy pro TV, které nemají příkaz sed
. Musím tedy místo sed "s/a/b/g". –
komentářů
Odpověď
Ano, existuje celá řada způsobů, jak toho dosáhnout. K provádění těchto činností můžete použít awk
, perl
nebo bash
. Obecně je však sed
nejvhodnějším nástrojem pro provádění těchto typů úkolů.
Příklady
Řekněme, že mám tato ukázková data, v souboru 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
Přímé úpravy
Výše uvedené příklady mohou také přímo upravovat soubory. Příklad Perlu je triviální. Jednoduše přidejte přepínač -i
.
$ perl -pie "s/foo/foofoofoo/g" data.txt
Pro awk
„je o něco méně přímý, ale stejně efektivní:
$ { rm data.txt && awk "{gsub("foo", "foofoofoo", $0); print}" > data.txt; } < data.txt
Tato metoda vytvoří dílčí shell se složenými závorkami“ {…} „, kde je soubor přesměrován do něj pomocí tohoto:
$ { ... } < data.txt
Jakmile je soubor přesměrován do dílčího shellu, je smazán a poté awk
je spuštěn proti obsahu souboru, který byl načten do dílčích skořápek STDIN. Tento obsah je poté zpracován programem awk
a zapsán zpět na stejný název souboru kterou jsme právě smazali, a účinně ji nahradíme.
Komentáře
- Děkuji za odpověď a zkusím to příští pracovní den. Nejsem si však jistý, jestli funguje to, protože nějaký příkaz nemusí v oříznutých linuxových systémech televize existovat, například ' sed '. Takže chci i nadále používat příkaz ' najít ', ' grep ' a tak dále.
- @binghenzq – Přidal jsem ' příklady, které inline upravují soubor.
- -1 Zřídka hlasuji, ale v tomto případě jde o otázka se zdála být spíše jednodušší metodou než jinou více / stejně složitou a pravděpodobně také závislou. Pokud by otázka byla jen o alternativách pro úplnou instalaci stroje * nix, pak bych pravděpodobně dal +1 této jinak dobré odpovědi.
- @MichaelDurrant – právě jsem přidal ty komplikované inline úpravy b / c, které o ně OP požádal . Také OP nastavil požadavek na NE používání
sed
ne I. Sed je vhodný nástroj pro provádění takových substitucí a on ' očividně žádá o lepší pochopení rolí těchto nástrojů, takže ukázat někomu tyto věci, i když jsou špatné, je nesmírně poučné ukázat jim proč. Příliš mnohokrát ppl ve znalostech jednoduše řekne " don ' nedělat to " aniž bych vysvětlil proč, tak jsem. Ale díky za alespoň zanechání komentáře, proč jste DV. - Jistě, myslel jsem si, že je to skvělá odpověď ve všech ostatních ohledech. jo, nesnáším -1 bez vysvětlení.
odpověď
Klasickou alternativou pro nahrazení jedním písmenem je tr
příkaz, který by měl být k dispozici téměř v každém systému:
$ echo "foobar" | tr a b foobbr
tr
je lepší než sed
, protože použití sed
(natož perl
nebo awk
) pro nahrazení jedním písmenem je jako použití kladiva k zabití mouchy.
grep
k tomu není určen, nemění svůj vstup, pouze v něm prohledává.
Alternativně můžete použít možnosti nahrazení některých skořápek. Zde pomocí ksh
, zsh
nebo bash
syntaxe:
$ foo="foobar" $ echo "${foo//a/b}" foobbr
Mohli bychom vám dát konkrétnější odpovědi, pokud byste přesně vysvětlili, jaký problém se snažíte vyřešit.
Komentáře
- Existuje možnost ignorovat velká písmena v
${foo//a/b}
? - @ AlikElzin-kilaka I ' se bojím ne. Musíte ' použít něco sofistikovanějšího typu, například:
echo "$foo" | sed 's/a/b/i
nebo zadat třídu znaků:echo ${foo//[aA]/b}
.
Odpověď
Můžete použít nástroj POSIX ex
:
ex a.txt <<eof %s/Sunday/Monday/g xit eof
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
Komentáře
- skvělé díky. stačí přidat, příznak -c znamená provést příkaz při zahájení editace (protože ex je editor) a příznak -s je buď režim skriptu zakazující zpětnou vazbu, nebo jak někteří říkají režim klienta. ref for more info: ex-vi.sourceforge.net/ex.html
Odpověď
Pokud pracujete spíše se souborem než se streamem, můžete použít standardní textový editor ed
:
printf "%s\n" ",s/a/b/g" w q | ed file.txt
To by mělo být k dispozici na libovolném * nix. Čárka v ",s/a/b/g"
říká ed
pro práci na každém řádku (můžete také použít %
, který bude známější, pokud jste zvyklí na vim), a zbytek z toho je standardní vyhledávání a nahrazování. w
říká, že má soubor zapsat (uložit), q
mu říká, že má skončit.
Všimněte si, že na rozdíl od možnost sed „s -i
(a podobné možnosti v jiných nástrojích), ve skutečnosti soubor upraví na místě, místo aby jej podváděl dočasnými soubory.
„Nemyslím si, že je to možné, aby to fungovalo se streamy, ale pak toho o ed
moc nevím a nepřekvapilo by mě, kdyby skutečně tuto schopnost měl (unixová filozofie je tím, čím je).
Odpověď
Použití předchůdce ed (ve kterém -s
znamená tichý (tichý) a čárka před příkazy znamená provedení na všech řádcích):
Jen tisk na STDOUT :
ed -s file <<! ,s/a/b/g ,p q !
nahrazení na místě:
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
. Kromě toho může mnoho nástrojů a jazyků také provádět výměnu řetězců prostého textu. Takže vaše otázka je nějak široká.