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
\Ljest rozszerzeniem GNU. -
\Ljak na razie działa dobrze. Podkreśl, że próbujesz wprowadzić rozszerzenie GNU - @JigarGandhi.
sedto 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.\Lnie 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
trimplementacje, takie jak GNUtrdon ' 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ć wariantsedlubawk' stolower(). - Niewielka korekta:
sed 's/.*/\L&/g' < input. Odniesienie\1do 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ż
trprzy 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 )