Czy przekonwertować cały tekst z wielkich na małe i odwrotnie?
17
Moje pytanie brzmi: jak mogę przekonwertować cały tekst z wielkich na małe i odwrotnie? To jest zmiana wielkości liter wszystkich liter. sedJakoś trzeba to zrobić z wymianą.
Twój drugi zakłada GNU sedi zmienną wielkość liter na wejściu. Użyj sed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'zamiast tego (wciąż specyficzne dla GNU). Pierwszy konwertuje tylko 26 liter łacińskich ASCII, a drugi konwertuje każdą literę rozpoznaną jako taką przez twoje ustawienia regionalne. Ten trma sens tylko w ustawieniach regionalnych ASCII. Ten perldziała tylko dla łacińskich liter ASCII.
Stéphane Chazelas
16
POSIXly, nie da się tego zrobić sedinaczej niż poprzez dostarczenie pełnego zestawu liter, które chcesz transliterować, jak pokazał @cuonglm .
Można to jednak zrobić za pomocą tri właśnie po to tr(transliteracja):
tr '[:lower:][:upper:]' '[:upper:][:lower:]'
Jednak w systemie Linux ma ograniczenia. Z 3 trimplementacji powszechnie spotykanych w systemach Linux:
z GNU tr, który działa tylko dla jednobajtowych zestawów znaków. Na przykład, Stéphane Chazelasw ustawieniach regionalnych UTF-8, to daje sTéPHANE cHAZELASzamiast sTÉPHANE cHAZELAS. To znane ograniczenie GNU tr.
z trzestawem narzędzi rodowych, to nie działa (dostajesz stéphane chazelas).
Tego nie trzrobi busyboks .
Na FreeBSD działa jednak OK. Można się spodziewać, że będzie działał dobrze również w certyfikowanych systemach uniksowych.
Czy w świecie komputerów tylko OSX to robi? Dlaczego to nie działa? Czy to tylko różne implementacje, ponieważ wydaje się, że istnieje ciągłe przesunięcie wartości szesnastkowej między wersją akcentowanego znaku z małą literą a jego wielkimi literami?
1
@ illuminÉ, nie jestem pewien, co masz na myśli przez określenie świata komputerów . AFAICS, problem dotyczy GNU, większość Unices ma „komputery stacjonarne”. Poza ASCII i niektórymi zestawami znaków iso8859, nie jestem świadomy, że można uogólnić przesunięcie heksadecymalne, co nie miałoby sensu w przypadku kodowania takiego jak UTF-8. Na przykład w UTF-8, wielkie litery ⴠ(e2 b4 a0) to Ⴠ(e1 83 80); zarówno i(69), jak i ı(c4 b1) mają I(49) jako wielkie litery (z wyjątkiem tureckich lokalizacji, w których się ipojawia İ). Powodem, dla którego nie działa z GNU, trjest to, że GNU trdziała z bajtami, a nie ze znakami.
Stéphane Chazelas,
W pewnym sensie miałem na myśli główny nurt, ale to naprawdę nie ma sensu, więc dziękuję za uwagi. Właśnie spojrzałem na francuskie znaki akcentowane (a tak naprawdę po prostu „é”) i podjąłem bardzo uproszczone założenia, zapominając ponownie, że chodzi o bajty. Ale ten rodowy? Przeczytam tę odpowiedź jeszcze raz!
1
@ illuminé, w przypadku pamiątki jest to inny problem, wygląda na to, że obsługuje tylko jedno wystąpienie [:lower:]lub [:upper:](więc pierwszy jest ignorowany). Nawet w języku francuskim œ -> Œjest c5 93 -> c5 92w UTF-8 i bd -> bcw iso8859-15.
Stéphane Chazelas,
2
Chociaż ma to już te same ograniczenia, co trrozwiązanie oferowane przez Stéphane Chazelas, jest to inny sposób:
I zrzucić stderrsię /dev/nulltam, ponieważ ddzapewnia również statystyki wszystkich swoich działań na 2deskryptorze pliku. Może to być przydatne w zależności od tego, co robisz, ale nie było w tej demonstracji. ddNadal obowiązują wszystkie inne rzeczy, które możesz zrobić , na przykład:
tr
byłoby bardziej odpowiednie niżsed
.Odpowiedzi:
Oto prosty sposób na
sed
:lub w skrócie z GNU
sed
, pracując z dowolnym znakiem, dla którego w twoim języku istnieje konwersja małych liter <->:jeśli możesz użyć innych narzędzi, takich jak:
perl
(ograniczone do liter ASCII):perl
(bardziej ogólnie):źródło
sed
i zmienną wielkość liter na wejściu. Użyjsed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'
zamiast tego (wciąż specyficzne dla GNU). Pierwszy konwertuje tylko 26 liter łacińskich ASCII, a drugi konwertuje każdą literę rozpoznaną jako taką przez twoje ustawienia regionalne. Tentr
ma sens tylko w ustawieniach regionalnych ASCII. Tenperl
działa tylko dla łacińskich liter ASCII.POSIXly, nie da się tego zrobić
sed
inaczej niż poprzez dostarczenie pełnego zestawu liter, które chcesz transliterować, jak pokazał @cuonglm .Można to jednak zrobić za pomocą
tr
i właśnie po totr
(transliteracja):Jednak w systemie Linux ma ograniczenia. Z 3
tr
implementacji powszechnie spotykanych w systemach Linux:tr
, który działa tylko dla jednobajtowych zestawów znaków. Na przykład,Stéphane Chazelas
w ustawieniach regionalnych UTF-8, to dajesTéPHANE cHAZELAS
zamiastsTÉPHANE cHAZELAS
. To znane ograniczenie GNUtr
.tr
zestawem narzędzi rodowych, to nie działa (dostajeszstéphane chazelas
).tr
zrobi busyboks .Na FreeBSD działa jednak OK. Można się spodziewać, że będzie działał dobrze również w certyfikowanych systemach uniksowych.
bash
Powłoka ma przypisanego operatora na to:Z
zsh -o extendedglob
:źródło
ⴠ
(e2 b4 a0) toჀ
(e1 83 80); zarównoi
(69), jak iı
(c4 b1) mająI
(49) jako wielkie litery (z wyjątkiem tureckich lokalizacji, w których sięi
pojawiaİ
). Powodem, dla którego nie działa z GNU,tr
jest to, że GNUtr
działa z bajtami, a nie ze znakami.[:lower:]
lub[:upper:]
(więc pierwszy jest ignorowany). Nawet w języku francuskimœ -> Œ
jestc5 93 -> c5 92
w UTF-8 ibd -> bc
w iso8859-15.Chociaż ma to już te same ograniczenia, co
tr
rozwiązanie oferowane przez Stéphane Chazelas, jest to inny sposób:WYNIK
I zrzucić
stderr
się/dev/null
tam, ponieważdd
zapewnia również statystyki wszystkich swoich działań na2
deskryptorze pliku. Może to być przydatne w zależności od tego, co robisz, ale nie było w tej demonstracji.dd
Nadal obowiązują wszystkie inne rzeczy, które możesz zrobić , na przykład:WYNIK:
źródło
aBc
nie jest konwertowany naAbC
).Jeśli Twoim głównym celem jest konwersja pliku z klasy niższej do wyższej, dlaczego nie używasz
tr
iSTDOUT
do konwersji pliku:Gdzie
FILENAME
jest twój oryginalny plik. GdzieFILENAME2
jest przekonwertowany plik wyjściowy.źródło
é
na przykład (przynajmniej w moim pliku).za pomocą
awk
:źródło
>file.txt
zacznie od obcięcia plikuruby
ma do tego metodę łańcuchową, podobne użycie z linii poleceń jakperl
Zobacz także kodowanie ruby-doc
źródło
Proste rzeczy proste. Filtr przeznaczony do tłumaczenia znaków to
tr
.źródło