Konwertuj zawartość pliku na małe litery

85

Mam tempplik z zawartością małych i dużych liter.

Wejście

Zawartość mojego temppliku:

hi
Jigar
GANDHI
jiga

Chcę przekonwertować wszystkie górne na dolne .

Komenda

Próbowałem następującego polecenia:

sed -e "s/[A-Z]/[a-z]/g" temp

ale otrzymałem zły wynik.

Wynik

Chcę to jako:

hi
jigar
gandhi
jiga

Co powinno znaleźć się w zastępczej części argumentu sed?

JigarGandhi
źródło

Odpowiedzi:

122

Jeśli dane wejściowe zawierają tylko znaki ASCII, możesz użyć tr:

tr A-Z a-z < input 

lub (mniej łatwe do zapamiętania i wpisania IMO; ale nie tylko litery alfabetu łacińskiego ASCII, choć 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

(tutaj przy założeniu implementacji GNU).

W POSIX sedmusisz określić wszystkie transliteracje, a następnie wybrać litery, które chcesz przekonwertować:

sed 'y/AǼBCΓDEFGH.../aǽbcγdefgh.../' < input

Z awk:

awk '{print tolower($0)}' < input
Anthon
źródło
3
Pamiętaj, że \Ljest to rozszerzenie GNU.
Anthon,
\Ljak dotąd działa dobrze dla mnie. W świetle punktu, w którym próbujesz dokonać rozszerzenia GNU
JigarGandhi,
2
@JigarGandhi. sedjest poleceniem uniksowym. Różne systemy mają różne warianty o różnych zachowaniach i funkcjach. Na szczęście w dzisiejszych czasach istnieje standard, który jest najbardziej zgodny, więc możesz liczyć na minimalny zestaw funkcji wspólnych dla wszystkich. \Lnie ma go wśród nich i został wprowadzony przez GNU sed(pasuje do tego samego operatora w standardzie ex/ vi) i ogólnie nie jest dostępny w innych implementacjach.
Stéphane Chazelas,
9
Zauważ, że niektóre trimplementacje, takie jak GNU tr, nie działają poprawnie w wielobajtowych lokalizacjach (większość z nich jest obecnie, echo STÉPHANE | tr '[:upper:]' '[:lower:]'na przykład spróbuj ). W systemach GNU, może wolisz sedwariant albo awk„s tolower().
Stéphane Chazelas,
5
Lekka korekta: sed 's/.*/\L&/g' < input. \1Odniesienie do dopasowanego podciągu nie będzie działać, jeśli podasz podciąg z nawiasie jako wurtle robi w jego. Jednak, &jak pokazano , jest nieco czystszy w reprezentowaniu całego meczu
Edward Brown
30

Korzystanie z vima jest bardzo proste:

$ vim filename
gg0guGZZ

Otwiera plik, ggprzechodzi do pierwszego wiersza 0, pierwszej kolumny. Dzięki guGobniża wielkość liter wszystkich znaków do końca pliku. ZZzapisuje i wychodzi.

Powinien obsłużyć prawie wszystko, co w niego rzucisz; zignoruje liczby, obsłuży inne niż ASCII.

Jeśli chcesz zrobić odwrotnie, zamień małe litery na wielkie, zamień una U: gg0gUGZZi gotowe.

TankorSmash
źródło
14
Lol „super proste”
blambert
to oczywiście nie skaluje się dobrze dla wielu plików
Corey Goldberg,
jak dotąd moja ulubiona odpowiedź !!!!
Mona Jalal,
1
@CoreyGoldberg vim file1 file2 fileetci wtedy coś :bufdo gg0guG:w<CR>będzie prawdopodobnie pracować dla dowolnej liczby plików. Jednak tego nie testowałem!
TankorSmash
@TankorSmash, który nadal nie jest skalowany do dużej liczby plików
Corey Goldberg
17

Sam to lubię dd.

<<\IN LC_ALL=C 2<>/dev/null \
dd conv=lcase
hi
Jigar 
GANDHI
jiga
IN

... dostaje ...

hi
jigar
ghandi
jiga

Ma LC_ALL=Cto na celu ochronę wszelkich wielobajtowych danych wejściowych - chociaż żadne wielobajtowe stolice nie będą konwertowane. To samo dotyczy (GNU) tr - obie aplikacje są podatne na wprowadzanie zniekształceń w dowolnym języku innym niż C. iconvmożna połączyć z jednym z nich, aby uzyskać kompleksowe rozwiązanie.

The 2>/dev/nullodrzutów przekierować dddomyślny raport stanu „s - i jego stderr. Bez tego ddnastąpiłoby zakończenie zadania takiego jak powyższe informacje o drukowaniu, takie jak liczba przetworzonych bajtów itp.

mikeserv
źródło
To rozwiązanie jest znacznie szybsze niż w trprzypadku obsługi dużych plików, dzięki!
WhiteWinterWolf
13

Możesz także użyć Perla 5:

perl -pe '$_=lc' temp

Opcja -pmówi Perlowi, aby uruchomił określone wyrażenie raz dla każdego wiersza wejścia, wypisując wynik, tj. Wartość końcową $_. -ewskazuje, że program będzie następnym argumentem, w przeciwieństwie do pliku zawierającego skrypt. lckonwertuje na małe litery. Bez argumentu będzie działać dalej $_. I $_=zapisuje to ponownie, aby zostało wydrukowane.

Byłaby to odmiana

perl -ne 'print lc' temp

Używanie -njest jak -pz wyjątkiem tego, $_że nie zostanie wydrukowane na końcu. Zamiast zapisywać w tej zmiennej, dołączam wyraźną instrukcję drukowania.

Jedną zaletą Perla w przeciwieństwie do sed jest to, że nie potrzebujesz żadnych rozszerzeń GNU. Istnieją projekty, które muszą być kompatybilne ze środowiskami innymi niż GNU, ale które mają już zależność Perla jako asa. W porównaniu z trtym może być tak, że Perl lcmoże być łatwiej rozpoznany przez ustawienia regionalne. Szczegółowe informacje można znaleźć na perllocalestronie podręcznika man.

MvG
źródło
9

Musisz uchwycić pasujący wzór, a następnie użyć go w zamian za pomocą modyfikatora:

sed 's/\([A-Z]\)/\L\1/g' temp

\(...\)„Wychwytuje” zakrywające dopasowany tekst, pierwszy idzie do przechwytywania \1, następny do \2itp Numeracja odpowiada otwarciu nawiasów w przypadku zagnieżdżonych zrzuty.

\LKonwertuje przechwycone wzór na małe litery, istnieje również \Una wielkie litery.

wurtel
źródło
3
nie musisz tego robić - cały wzór jest zawsze przyłapany&
mikeserv
To prawda, ale nie skorzystałbym z okazji, aby wyjaśnić przechwytywanie meczów :-)
wurtel,