Mám soubor temp
s malým a velkým obsahem.
Vstup
Obsah mého temp
souboru:
hi Jigar GANDHI jiga
Chci převést všechny horní na dolní .
Příkaz
Zkoušel jsem následující příkaz:
sed -e "s/[A-Z]/[a-z]/g" temp
, ale dostal jsem špatný výstup.
Výstup
Chci to jako:
hi jigar gandhi jiga
Co musí být v náhradní části argumentu pro sed
?
Komentáře
- Viz také Jak převést soubory txt UTF-8 na všechna velká písmena v bash?
Odpovědět
Pokud váš vstup obsahuje pouze znaky ASCII, můžete použít tr
jako:
nebo (méně snadno zapamatovatelné a psát IMO; ale není omezen na latinská písmena ASCII, i když v některých implementacích včetně GNU tr
je stále omezen na jednobajtové znaky, takže v národních prostředích UTF-8, stále omezen na písmena ASCII):
tr "[:upper:]" "[:lower:]" < input
pokud musíte použít sed
:
sed "s/.*/\L&/g" < input
(zde za předpokladu implementace GNU).
S POSIX sed
musíte zadat všechny přepisy a pak si můžete vybrat, které písmena, která chcete převést:
sed "y/AǼBCΓDEFGH.../aǽbcγdefgh.../" < input
S awk
:
awk "{print tolower($0)}" < input
Komentáře
- Upozorňujeme, že
\L
je přípona GNU. -
\L
pro mě zatím funguje dobře. Osvětlete bod, který se snažíte vytvořit příponu GNU - @JigarGandhi.
sed
je příkaz Unix. Různé systémy mají různé varianty s odlišným chováním a d funkčnost. Naštěstí dnes existuje ' standard, který nejvíce vyhovuje, takže můžete počítat s minimální sadou funkcí společných pro všechny.\L
mezi nimi není a byl představen GNUsed
(odpovídá stejnému operátorovi ve standarduex
/vi
) a v jiných implementacích obecně není k dispozici. - Upozorňujeme, že některé
tr
implementace jako GNUtr
nefunguje ' správně ve vícebajtových národních prostředích (většina z nich je dnes, zkusteecho STÉPHANE | tr '[:upper:]' '[:lower:]'
například). V systémech GNU můžete upřednostňovatsed
variantu neboawk
' stolower()
. - Mírná korekce:
sed 's/.*/\L&/g' < input
. Odkaz\1
na odpovídající podřetězec nebude fungovat ' pokud nezadáte podřetězec se závorkami, jak to dělá wurtle v jeho. Je však ' mírně čistší použít&
k reprezentaci celé shody, jak je znázorněno
Odpověď
Pomocí vim je to velmi jednoduché:
$ vim filename gg0guGZZ
Otevře soubor gg
přejde na první řádek, 0
, první sloupec. S guG
, zmenší velikost písmen všech znaků až do spodní části souboru. ZZ
uloží a ukončí.
Měl by zpracovávat téměř všechno, co na něj vrhnete; „Il ignore numbers, it“ ll handle non ASCII.
Pokud jste chtěli udělat opak, změňte malá písmena na velká a vyměňte u
Vyzkoušejte U
: gg0gUGZZ
a jste připraveni.
Komentáře
- Lol " super jednoduchý "
- toto samozřejmě ' dobře škálovat mnoho souborů
- @CoreyGoldberg
vim file1 file2 fileetc
a pak něco jako:bufdo gg0guG:w<CR>
by pravděpodobně pracovat pro libovolný počet souborů. Netestovali jste to! - @TankorSmash, který stále ' t nezvětšuje velký počet souborů
Odpověď
Líbí se mi dd
.
<<\IN LC_ALL=C 2<>/dev/null \ dd conv=lcase hi Jigar GANDHI jiga IN
… získá …
hi jigar ghandi jiga
LC_ALL=C
slouží k ochraně jakýchkoli vícebajtů na vstupu – ačkoli všechna vícebajtová hlavní města nebudou převedena. To samé platí pro (GNU) tr
– obě aplikace jsou náchylné k manglování v jakémkoli národním prostředí mimo C. iconv
lze kombinovat s oběma pro komplexní řešení.
2>/dev/null
přesměrování zahodí dd
výchozí stavovou zprávu – a její stderr. Bez ní dd
bude následovat po dokončení úlohy, jako jsou výše uvedené, s informacemi o tisku, například kolik bytů bylo zpracováno atd.
Komentáře
- Toto řešení je mnohem rychlejší než
tr
při zpracování velkých souborů, děkuji!
Odpovědět
Můžete také použít Perl 5:
perl -pe "$_=lc" temp
Volba -p
říká perl spustit zadaný výraz jednou pro každý řádek vstupu, tisknout výsledek, tj. konečnou hodnotu $_
. -e
označuje, že program bude dalším argumentem, na rozdíl od souboru obsahujícího skript. lc
se převede na malá písmena. Bez argumentu bude fungovat na $_
. A $_=
to znovu uloží, aby se vytisklo.
Varianta by byla
perl -ne "print lc" temp
Použití -n
je jako -p
kromě toho, že $_
se nakonec nevytiskne. Takže místo toho, abych ukládal do této proměnné, zahrnuji výslovné tiskové prohlášení.
Jednou z výhod Perlu na rozdíl od sed je to, že nepotřebujete žádná rozšíření GNU. Existují projekty, které musí být kompatibilní s prostředími, které nejsou GNU, ale také již mají Perl závislost. Ve srovnání s tr
se může stát, že Perl lc
lze snáze přizpůsobit národnímu prostředí. Podrobnosti najdete na perllocale
man stránce.
Odpověď
Musíte zachytit odpovídající vzor a poté jej použít v nahrazení s modifikátorem:
sed "s/\([A-Z]\)/\L\1/g" temp
\(...\)
„zachycuje“ při uzavření shodného textu přejde první zachycení na \1
, další na \2
atd. Číslování je podle úvodních závorek v případě vnořené zachycení.
\L
převádí zachycený vzor na malá písmena, existuje také \U
pro velká písmena .
Komentáře
- nemusíte to dělat – celý vzor je vždy zachycen v
&
- Je to pravda, ale pak bych si nechal ujít příležitost vysvětlit zachycení zápasů 🙂
Odpověď
Kromě odpovědi MvG můžete také použít Perl 6:
perl6 -pe .=lc temp
Zde je $ _ implicitní a nepotřebujete jednoduché uvozovky, abyste jej chránili před rozšířením o shell ($ _ je speciální parametr Bash; viz: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )