Mam plik temp
z małą i dużą zawartością.
Dane wejściowe
Zawartość mojego temp
pliku:
hi Jigar GANDHI jiga
Chcę przekonwertować wszystkie z wyższych na niższe .
Polecenie
Próbowałem wykonać następujące polecenie:
sed -e "s/[A-Z]/[a-z]/g" temp
, ale otrzymałem błędne wyjście.
Wyjście
Chcę, aby było to jako:
hi jigar gandhi jiga
Co musi być w części substytut of argument for sed
?
Komentarze
- Zobacz także Jak przekonwertować pliki txt UTF-8 na wszystkie wielkie litery w bash?
Odpowiedź
Jeśli dane wejściowe zawierają tylko znaki ASCII, możesz użyć tr
, na przykład:
lub (mniej łatwe do zapamiętania i wpisz IMO; ale nie ograniczając się do łacińskich liter ASCII, chociaż w niektórych implementacjach, w tym GNU tr
, nadal ograniczone do znaków jednobajtowych, więc w ustawieniach regionalnych UTF-8 nadal ograniczone do liter ASCII):
tr "[:upper:]" "[:lower:]" < input
jeśli musisz użyć sed
:
sed "s/.*/\L&/g" < input
(zakładając implementację GNU).
W POSIX sed
, musisz określić wszystkie transliteracje, a następnie wybrać, które litery, które chcesz przekonwertować:
sed "y/AǼBCΓDEFGH.../aǽbcγdefgh.../" < input
Z awk
:
awk "{print tolower($0)}" < input
Komentarze
- Należy pamiętać, że
\L
jest rozszerzeniem GNU. -
\L
jak na razie działa dobrze. Podkreśl, że próbujesz wprowadzić rozszerzenie GNU - @JigarGandhi.
sed
to polecenie Uniksa. Różne systemy mają różne warianty z różnym zachowaniem d funkcjonalność. Na szczęście w dzisiejszych czasach ' jest standardem, który jest najbardziej zgodny, więc możesz liczyć na minimalny zestaw funkcji wspólnych dla wszystkich.\L
nie ma wśród nich i zostało wprowadzone przez GNUsed
(pasuje do tego samego operatora w standardowymex
/vi
) i generalnie nie jest dostępny w innych implementacjach. - Zwróć uwagę, że niektóre
tr
implementacje, takie jak GNUtr
don ' nie działają poprawnie w lokalizacjach wielobajtowych (większość z nich to obecnie, wypróbujecho STÉPHANE | tr '[:upper:]' '[:lower:]'
na przykład). W systemach GNU możesz preferować wariantsed
lubawk
' stolower()
. - Niewielka korekta:
sed 's/.*/\L&/g' < input
. Odniesienie\1
do dopasowanego podciągu won ' nie działa, chyba że podasz podciąg w nawiasach, tak jak robi to wurtle. Jednak ' jest nieco bardziej przejrzyste użycie elementu&
do reprezentowania całego dopasowania, jak pokazano
Odpowiedź
Używając vim, jest to bardzo proste:
$ vim filename gg0guGZZ
Otwiera plik gg
przechodzi do pierwszego wiersza, 0
, pierwsza kolumna. Z guG
, zmniejsza wielkość liter do końca pliku. ZZ
zapisuje i kończy pracę.
Powinien obsłużyć prawie wszystko, co do niego rzucisz; „Ignorujemy liczby, to” będzie obsługiwać inne niż ASCII.
Jeśli chcesz zrobić odwrotnie, zamień małe litery na duże, zamień u
na U
: gg0gUGZZ
i jesteś gotowy.
Komentarze
- Lol ” super proste ”
- to oczywiście nie działa ' t dobrze skaluje się dla wielu plików
- @CoreyGoldberg
vim file1 file2 fileetc
, a wtedy coś takiego jak:bufdo gg0guG:w<CR>
prawdopodobnie działa dla dowolnej liczby plików. Nie testowałem tego jednak! - @TankorSmash, który nadal nie ' t skaluje się do dużej liczby plików
Odpowiedź
Ja lubię dd
.
<<\IN LC_ALL=C 2<>/dev/null \ dd conv=lcase hi Jigar GANDHI jiga IN
… pobiera …
hi jigar ghandi jiga
LC_ALL=C
służy do ochrony wszelkich wielobajtowych danych wejściowych – chociaż wszelkie wielobajtowe wielkie litery nie zostaną przekonwertowane. To samo dotyczy (GNU) tr
– obie aplikacje są podatne na zniekształcanie danych wejściowych w dowolnej lokalizacji innej niż C. iconv
można połączyć z jednym i drugim, aby uzyskać kompleksowe rozwiązanie.
2>/dev/null
przekierowanie odrzuca domyślny raport o stanie dd
– i jego błąd stderr. Bez niego dd
nastąpiłoby po zakończeniu zadania takiego jak powyższe z wypisywaniem informacji, takich jak liczba przetworzonych bajtów itp.
Komentarze
- To rozwiązanie jest znacznie szybsze niż
tr
przy obsłudze dużych plików, dzięki!
Odpowiedź
Możesz także użyć Perla 5:
perl -pe "$_=lc" temp
Opcja -p
mówi perl, aby uruchomić określone wyrażenie raz dla każdego wiersza wejścia, wypisując wynik, tj. końcową wartość $_
. -e
wskazuje, że program będzie następnym argumentem, w przeciwieństwie do pliku zawierającego skrypt. lc
konwertuje na małe litery. Bez argumentu będzie działać na $_
. I $_=
zapisuje to ponownie, aby zostało wydrukowane.
Odmianą tego byłoby
perl -ne "print lc" temp
Używanie -n
jest jak -p
z wyjątkiem tego, że $_
nie zostanie ostatecznie wydrukowany. Więc zamiast zapisywać do tej zmiennej, dołączam wyraźną instrukcję print.
Jedną z zalet Perla w przeciwieństwie do seda jest to, że nie potrzebujesz żadnych rozszerzeń GNU. Istnieją projekty, które muszą być kompatybilne ze środowiskami innymi niż GNU, ale które również mają już zależność od Perla. W porównaniu z tr
może się zdarzyć, że Perl lc
będzie łatwiej uwzględniał ustawienia regionalne. Zobacz stronę podręcznika perllocale
, aby uzyskać szczegółowe informacje.
Odpowiedź
Musisz przechwycić dopasowany wzorzec, a następnie użyj go w zamianie z modyfikatorem:
sed "s/\([A-Z]\)/\L\1/g" temp
\(...\)
„przechwytuje” obejmując dopasowany tekst, pierwsze przechwycenie trafia do \1
, następne do \2
itd. Numeracja jest zgodna z nawiasami otwierającymi w przypadku zagnieżdżone przechwytywania.
\L
konwertuje przechwycony wzorzec na małe litery, jest też \U
dla wielkich liter .
Komentarze
- nie musisz tego robić – cały wzorzec jest zawsze przechwytywany w
&
- Prawda, ale wtedy przegapiłbym okazję wyjaśnienia przechwytywania dopasowań 🙂
Odpowiedź
Oprócz odpowiedzi MvG można również użyć Perla 6:
perl6 -pe .=lc temp
Tutaj $ _ jest niejawne i nie potrzebujesz pojedynczych cudzysłowów, aby chronić go przed interpretacją przez powłokę ($ _ jest specjalnym parametrem Bash; zobacz: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )