Konwertuj zawartość pliku na małe litery

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

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 GNU sed (pasuje do tego samego operatora w standardowym ex / vi) i generalnie nie jest dostępny w innych implementacjach.
  • Zwróć uwagę, że niektóre tr implementacje, takie jak GNU tr don ' nie działają poprawnie w lokalizacjach wielobajtowych (większość z nich to obecnie, wypróbuj echo STÉPHANE | tr '[:upper:]' '[:lower:]' na przykład). W systemach GNU możesz preferować wariant sed lub awk ' s tolower().
  • 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 )

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *