Uwaga: YMMV w tym przypadku. Nie działa dla mnie (GNU bash w wersji 4.2.46 i 4.0.33 (i to samo zachowanie 2.05b.0, ale nocasematch nie jest zaimplementowany)) nawet przy użyciu shopt -u nocasematch;. Wyłączenie tej opcji nocasematch powoduje, że [["fooBaR" == "FOObar"]] pasuje do OK ALE dziwnie wewnątrz skrzynki [bz] są niepoprawnie dopasowane do [AZ] Bash jest zdezorientowany podwójnie ujemnym („niepokojącym nocasematch”)! :-)
Czy coś pomijam, czy może twój ostatni przykład (w Bash) robi coś zupełnie innego? Działa dla „ABX”, ale jeśli zamiast tego zrobisz word="Hi All"podobnie jak w innych przykładach, to hanie hi all. Działa tylko w przypadku wielkich liter i pomija już małe litery.
jangosteve
26
Zauważ, że tylko tri awkprzykłady są określone w standardzie POSIX.
Richard Hansen
178
tr '[:upper:]' '[:lower:]'użyje bieżących ustawień narodowych do określenia odpowiedników wielkich / małych liter, więc będzie działać z ustawieniami narodowymi, które używają liter ze znakami diakrytycznymi.
Richard Hansen
10
Jak uzyskać wynik w nowej zmiennej? Tzn. Chcę, aby ciąg małych liter był nową zmienną?
Adam Parkin,
60
@Adam:b="$(echo $a | tr '[A-Z]' '[a-z]')"
Tino
434
W Bash 4:
Na małe litery
$ string="A FEW WORDS"
$ echo "${string,}"
a FEW WORDS
$ echo "${string,,}"
a few words
$ echo "${string,,[AEIUO]}"
a FeWWoRDS
$ string="A Few Words"
$ declare -l string
$ string=$string; echo "$string"
a few words
Do wielkich liter
$ string="a few words"
$ echo "${string^}"
A few words
$ echo "${string^^}"
A FEW WORDS
$ echo "${string^^[aeiou]}"
A fEw wOrds
$ string="A Few Words"
$ declare -u string
$ string=$string; echo "$string"
A FEW WORDS
Przełącz (nieudokumentowane, ale opcjonalnie konfigurowalne w czasie kompilacji)
$ string="A Few Words"
$ echo "${string~~}"
a fEW wORDS
$ string="A FEW WORDS"
$ echo "${string~}"
a FEW WORDS
$ string="a few words"
$ echo "${string~}"
A few words
Wielkie litery (nieudokumentowane, ale opcjonalnie konfigurowalne w czasie kompilacji)
$ string="a few words"
$ declare -c string
$ string=$string
$ echo "$string"
A few words
Tytuł sprawy:
$ string="a few words"
$ string=($string)
$ string="${string[@]^}"
$ echo "$string"
A FewWords
$ declare -c string
$ string=(a few words)
$ echo "${string[@]}"
A FewWords
$ string="a FeW WOrdS"
$ string=${string,,}
$ string=${string~}
$ echo "$string"
A few words
Aby wyłączyć declareatrybut, użyj +. Na przykład declare +c string. Wpływa to na kolejne przypisania, a nie na bieżącą wartość.
Te declareopcje zmienić atrybut zmiennej, ale nie zawartość. Ponowne przypisania w moich przykładach aktualizują zawartość, aby pokazać zmiany.
Edytować:
Dodano „przełącz pierwszy znak po słowie” ( ${var~}) zgodnie z sugestią ghostdog74 .
Edycja: Poprawiono zachowanie tyldy, aby pasowało do Bash 4.3.
Dość bizzare, operatory „^^” i „,,” nie działają na znakach spoza ASCII, ale „~~” działa… Zwróci więc string="łódź"; echo ${string~~}„ŁÓDŹ”, ale echo ${string^^}zwróci „łóDź”. Nawet w LC_ALL=pl_PL.utf-8. To używa bash 4.2.24.
Hubert Kario
2
@HubertKario: To dziwne. To samo dla mnie w Bash 4.0.33 z tym samym ciągiem w en_US.UTF-8. To błąd i zgłosiłem go.
Wstrzymano do odwołania.
1
@HubertKario: Spróbuj echo "$string" | tr '[:lower:]' '[:upper:]'. Prawdopodobnie wykaże tę samą awarię. Tak więc problem przynajmniej częściowo nie dotyczy Basha.
Wstrzymano do odwołania.
1
@DennisWilliamson: Tak, też to zauważyłem (patrz komentarz do odpowiedzi Shuvalova). Powiedziałbym tylko: „te rzeczy są tylko dla ASCII”, ale potem działa operator „~~”, więc to nie tak, że nie ma już tabel kodu i tłumaczeń ...
Hubert Kario
4
@HubertKario: Opiekun Bash potwierdził błąd i stwierdził, że zostanie on naprawiony w następnej wersji.
@RichardHansen: trnie działa dla mnie dla znaków spoza ACII. Mam prawidłowy zestaw ustawień regionalnych i wygenerowane pliki ustawień narodowych. Masz pojęcie, co mogę zrobić źle?
Hubert Kario
FYI: To działało na Windows / Msys. Niektóre inne sugestie nie.
+1 a="$(tr [A-Z] [a-z] <<< "$a")"wygląda dla mnie najłatwiej. Nadal jestem początkującym ...
Sandeepan Nath
2
Zdecydowanie polecam sedrozwiązanie; Pracowałem w środowisku, które z jakiegoś powodu nie ma, trale jeszcze nie znalazłem systemu bez sed, a poza tym dużo czasu chcę to zrobić. Właśnie zrobiłem coś innego, sedwięc mogę połączyć polecenia razem w jedną (długą) instrukcję.
Haravikk,
2
Wyrażenia w nawiasach powinny być cytowane. W tr [A-Z] [a-z] Apowłoce może wykonać rozszerzenie nazwy pliku, jeśli istnieją nazwy plików składające się z jednej litery lub ustawiono nullgob . tr "[A-Z]" "[a-z]" Abędzie się zachowywał poprawnie.
Dennis,
2
@CamiloMartin to system BusyBox, w którym mam ten problem, szczególnie Synology NAS, ale napotkałem go również na kilku innych systemach. Ostatnio robiłem wiele skryptów powłoki między platformami, a wymaganie, aby nic więcej nie było instalowane, czyni to bardzo trudnym! Jednak jeszcze nie spotkałem systemu bezsed
Haravikk
2
Pamiętaj, że tr [A-Z] [a-z]jest nieprawidłowy w prawie wszystkich lokalizacjach. na przykład w en-USustawieniach regionalnych A-Zjest faktycznie interwał AaBbCcDdEeFfGgHh...XxYyZ.
fuz
44
Wiem, że to stary post, ale podałem tę odpowiedź dla innej witryny, więc pomyślałem, że opublikuję ją tutaj:
GÓRNA -> dolna : użyj Pythona:
b=`echo "print '$a'.lower()" | python`
Lub Ruby:
b=`echo "print '$a'.downcase" | ruby`
Lub Perl (prawdopodobnie mój ulubiony):
b=`perl -e "print lc('$a');"`
Lub PHP:
b=`php -r "print strtolower('$a');"`
Lub Awk:
b=`echo "$a" | awk '{ print tolower($1) }'`
Lub Sed:
b=`echo "$a" | sed 's/./\L&/g'`
Lub Bash 4:
b=${a,,}
Lub NodeJS, jeśli go masz (i jesteś trochę szalony ...):
@JESii oba działają dla mnie górna -> dolna i dolna-> górna. Używam sed 4.2.2 i Bash 4.3.42 (1) na 64bit Debian Stretch.
nettux,
1
Cześć, @ nettux443 ... Właśnie próbowałem ponownie wykonać operację bash i nadal nie udaje mi się komunikat o błędzie „złe podstawienie”. Jestem na OSX, używając bash homebrew: GNU bash, wersja 4.3.42 (1) -release (x86_64-apple-darwin14.5.0)
JESii
5
Nie używaj! Wszystkie przykłady generujące skrypt są wyjątkowo kruche; jeśli wartość azawiera pojedynczy cytat, masz nie tylko zepsute zachowanie, ale poważny problem z bezpieczeństwem.
tripleee
Najbardziej podoba mi się rozwiązanie sed, ponieważ sed jest zawsze wszechobecny.
Dudi Boy,
Wolę używać rozwiązania dd. Pamiętaj, że musisz mieć
Zastanawiam się, czy nie pozwoliłeś na odrobinę szaleństwa w tym skrypcie, ponieważ nie jest on przenośny na FreeBSD sh: $ {1: $ ...}: Złe podstawienie
Dereckson
2
W rzeczy samej; podciągi z ${var:1:1}są Bashizmem.
tripleee
To podejście ma dość złe wskaźniki wydajności. Zobacz moją odpowiedź na dane.
Chciałbym podziękować za polecenie, którym chcę się podzielić, ale prawda jest taka, że uzyskałem je na własny użytek ze strony http://commandlinefu.com . Ma tę zaletę, że jeśli cdprzejdziesz do dowolnego katalogu w swoim własnym folderze domowym, to znaczy zmieni wszystkie pliki i foldery na małe litery rekurencyjnie, używaj ostrożnie. Jest to doskonała poprawka do wiersza poleceń i szczególnie przydatna w przypadku wielu albumów przechowywanych na dysku.
Możesz podać katalog zamiast kropki (.) Po znalezieniu, który oznacza bieżący katalog lub pełną ścieżkę.
Mam nadzieję, że to rozwiązanie okaże się użyteczne. Jedyną rzeczą, której nie robi to polecenie, jest zastąpienie spacji znakami podkreślenia - no cóż, może innym razem.
Nie działało to dla mnie z jakiegokolwiek powodu, choć wygląda dobrze. Udało mi się to jednak alternatywnie: znaleźć. -exec / bin / bash -c 'mv {} `tr [AZ] [az] <<< {}`' \;
John Rix
To wymaga prenameod perl: dpkg -S "$(readlink -e /usr/bin/rename)"dajeperl: /usr/bin/prename
Tino
4
Wiele odpowiedzi za pomocą zewnętrznych programów, które tak naprawdę nie są używane Bash.
Jeśli wiesz, że będziesz mieć dostępną wersję Bash4, powinieneś po prostu użyć ${VAR,,}notacji (jest to łatwe i fajne). W przypadku wersji Bash przed 4 (na moim komputerze Mac nadal jest używana wersja Bash 3.2). Użyłem poprawionej wersji odpowiedzi @ ghostdog74, aby stworzyć bardziej przenośną wersję.
Możesz zadzwonić lowercase 'my STRING'i uzyskać małą wersję. Czytam komentarze na temat ustawiania wyniku na var, ale to nie jest tak naprawdę przenośne Bash, ponieważ nie możemy zwrócić ciągów. Drukowanie to najlepsze rozwiązanie. Łatwy do uchwycenia za pomocą czegoś takiego var="$(lowercase $str)".
Jak to działa
Działa to poprzez uzyskanie reprezentacji liczb całkowitych ASCII każdego znaku za pomocą, printfa następnie adding 32if upper-to->lowerlub subtracting 32if lower-to->upper. Następnie użyj printfponownie, aby przekonwertować liczbę z powrotem na znak. Od 'A' -to-> 'a'mamy różnicę 32 znaków.
Za pomocą printfwyjaśnienia:
$ printf "%d\n""'a"97
$ printf "%d\n""'A"65
97 - 65 = 32
A to jest wersja robocza z przykładami.
Zwróć uwagę na komentarze w kodzie, ponieważ wyjaśniają wiele rzeczy:
#!/bin/bash# lowerupper.sh# Prints the lowercase version of a char
lowercaseChar(){case"$1"in[A-Z])
n=$(printf "%d""'$1")
n=$((n+32))
printf \\$(printf "%o""$n");;*)
printf "%s""$1";;esac}# Prints the lowercase version of a sequence of strings
lowercase(){
word="$@"for((i=0;i<${#word};i++));do
ch="${word:$i:1}"
lowercaseChar "$ch"done}# Prints the uppercase version of a char
uppercaseChar(){case"$1"in[a-z])
n=$(printf "%d""'$1")
n=$((n-32))
printf \\$(printf "%o""$n");;*)
printf "%s""$1";;esac}# Prints the uppercase version of a sequence of strings
uppercase(){
word="$@"for((i=0;i<${#word};i++));do
ch="${word:$i:1}"
uppercaseChar "$ch"done}# The functions will not add a new line, so use echo or# append it if you want a new line after printing# Printing stuff directly
lowercase "I AM the Walrus!"$'\n'
uppercase "I AM the Walrus!"$'\n'
echo "----------"# Printing a var
str="A StRing WITH mixed sTUFF!"
lowercase "$str"$'\n'
uppercase "$str"$'\n'
echo "----------"# Not quoting the var should also work, # since we use "$@" inside the functions
lowercase $str$'\n'
uppercase $str$'\n'
echo "----------"# Assigning to a var
myLowerVar="$(lowercase $str)"
myUpperVar="$(uppercase $str)"
echo "myLowerVar: $myLowerVar"
echo "myUpperVar: $myUpperVar"
echo "----------"# You can even do stuff likeif[['option 2'="$(lowercase 'OPTION 2')"]];then
echo "Fine! All the same!"else
echo "Ops! Not the same!"fi
exit 0
A wyniki po uruchomieniu tego:
$ ./lowerupper.sh
i am the walrus!
I AM THE WALRUS!----------
a string with mixed stuff!
A STRING WITH MIXED STUFF!----------
a string with mixed stuff!
A STRING WITH MIXED STUFF!----------
myLowerVar: a string with mixed stuff!
myUpperVar: A STRING WITH MIXED STUFF!----------Fine!All the same!
Powinno to jednak działać tylko w przypadku znaków ASCII .
Dla mnie jest w porządku, ponieważ wiem, że przekażę mu tylko znaki ASCII.
Używam tego na przykład do niektórych opcji CLI bez rozróżniania wielkości liter.
Konwersja jest wykonywana tylko dla alfabetów. Więc to powinno działać dobrze.
Koncentruję się na konwersji alfabetów między az z wielkich na małe litery. Wszelkie inne postacie powinny być po prostu wydrukowane w stdout, ponieważ jest ...
Konwertuje cały tekst w ścieżce / na / plik / nazwę pliku z zakresu az na AZ
Do konwersji małych i wielkich liter
cat path/to/file/filename | tr 'a-z''A-Z'
Do konwersji z wielkich na małe litery
cat path/to/file/filename | tr 'A-Z''a-z'
Na przykład,
Nazwa pliku:
my name is xyz
zostanie przekonwertowany na:
MY NAME IS XYZ
Przykład 2:
echo "my name is 123 karthik"| tr 'a-z''A-Z'# Output:# MY NAME IS 123 KARTHIK
Przykład 3:
echo "my name is 123 &&^&& #@$#@%%& kAR2~thik"| tr 'a-z''A-Z'# Output:# MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK
Jeśli używasz v4, jest to włączone . Jeśli nie, oto proste, szeroko stosowane rozwiązanie. Inne odpowiedzi (i komentarze) w tym wątku były bardzo pomocne w tworzeniu poniższego kodu.
# Like echo, but converts to lowercase
echolcase (){
tr [:upper:][:lower:]<<<"${*}"}# Takes one arg by reference (var name) and makes it lowercase
lcase (){eval"${1}"=\'$(echo ${!1//\'/"'\''"}| tr [:upper:][:lower:])\'
}
Nie jest zły! Aby przeanalizować skuteczność tego podejścia, zobacz moją odpowiedź dotyczącą wskaźników.
Dejay Clayton
3
Pomimo wieku tego pytania i podobnego do odpowiedzi udzielonej przez technozaura . Trudno mi było znaleźć rozwiązanie, które byłoby przenośne na większości platform (których używam), a także na starszych wersjach bash. Byłem również sfrustrowany tablicami, funkcjami i wykorzystaniem wydruków, echa i plików tymczasowych do wyszukiwania trywialnych zmiennych. Działa to dla mnie bardzo dobrze. Moje główne środowiska testowe to:
GNU bash, wersja 4.1.2 (1) -release (x86_64-redhat-linux-gnu)
GNU bash, wersja 3.2.57 (1) -release (sparc-sun-solaris2.10)
lcs="abcdefghijklmnopqrstuvwxyz"
ucs="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
input="Change Me To All Capitals"for(( i=0; i<"${#input}"; i++));do:for(( j=0; j<"${#lcs}"; j++));do:if[["${input:$i:1}"=="${lcs:$j:1}"]];then
input="${input/${input:$i:1}/${ucs:$j:1}}"fidonedone
Prosty styl C dla pętli do iteracji po łańcuchach. W poniższej linii, jeśli nie widziałeś czegoś takiego wcześniej,
tutaj się tego nauczyłem . W tym przypadku wiersz sprawdza, czy znak $ {input: $ i: 1} (małe litery) istnieje w danych wejściowych, a jeśli tak, to zastępuje go danym znakiem $ {ucs: $ j: 1} (wielkie litery) i przechowuje go z powrotem do wejścia.
Jest to niezwykle nieefektywne, zapętla 650 razy w powyższym przykładzie i zajmuje 35 sekund na wykonanie 1000 wywołań na mojej maszynie. Aby znaleźć alternatywę, która zapętla się tylko 11 razy i zajmuje mniej niż 5 sekund na wykonanie 1000 wywołań, zobacz moją alternatywną odpowiedź.
Dejay Clayton
1
Dzięki, chociaż powinno to być oczywiste po prostu patrząc na to. Być może błędy strony wynikają z wielkości wejściowej i liczby wykonywanych iteracji. Niemniej jednak podoba mi się twoje rozwiązanie.
JaredTS486,
3
Jest to znacznie szybsza odmiana podejścia JaredTS486, który wykorzystuje natywne możliwości Bash (w tym wersje Bash <4.0) do optymalizacji swojego podejścia.
Zmierzyłem czas 1000 iteracji tego podejścia dla małego ciągu (25 znaków) i większego ciągu (445 znaków), zarówno dla konwersji małych jak i wielkich liter. Ponieważ ciągi testowe są przeważnie pisane małymi literami, konwersje na małe litery są na ogół szybsze niż na wielkie.
Porównałem swoje podejście z kilkoma innymi odpowiedziami na tej stronie, które są kompatybilne z Bash 3.2. Moje podejście jest znacznie bardziej wydajne niż większość podejść tutaj udokumentowanych i jest nawet szybsze niż trw kilku przypadkach.
Oto wyniki synchronizacji dla 1000 iteracji po 25 znaków:
0,46 s za moje podejście do małych liter; 0,96s dla wielkich liter
75s za podejście ghostdog74 do małych liter; 669s dla wielkich liter. Warto zauważyć, jak dramatyczna jest różnica w wydajności między testem z dominującymi meczami a testem z dominującymi chybcami
660 dla podejścia JaredTS486 do małych liter; 660s na wielkie litery. Warto zauważyć, że takie podejście generowało ciągłe błędy stron (zamiana pamięci) w Bash
Podejście jest proste: podczas gdy w ciągu wejściowym znajdują się pozostałe wielkie litery, znajdź następną i zamień wszystkie wystąpienia tej litery na jej małą literę. Powtarzaj, aż wszystkie wielkie litery zostaną zastąpione.
Niektóre cechy wydajności mojego rozwiązania:
Używa tylko wbudowanych narzędzi powłoki, co pozwala uniknąć nakładania się na zewnętrzne narzędzia binarne w nowym procesie
Unika podpowłok, które podlegają karom za wydajność
Korzysta z mechanizmów powłoki, które zostały skompilowane i zoptymalizowane pod kątem wydajności, takich jak globalne zastępowanie ciągów zmiennych, przycinanie sufiksu zmiennych oraz wyszukiwanie i dopasowanie wyrażeń regularnych. Mechanizmy te są znacznie szybsze niż ręczne iterowanie po łańcuchach
Pętle tylko tyle razy, ile wymaga liczba unikatowych pasujących znaków do konwersji. Na przykład konwersja łańcucha zawierającego trzy różne wielkie litery na małe wymaga tylko 3 iteracji pętli. W przypadku wstępnie skonfigurowanego alfabetu ASCII maksymalna liczba iteracji pętli wynosi 26
Odpowiedzi:
Istnieją różne sposoby:
Standard POSIX
tr
AWK
Bez POSIX
Mogą wystąpić problemy z przenośnością z następującymi przykładami:
Bash 4.0
sed
Perl
Grzmotnąć
Uwaga: YMMV w tym przypadku. Nie działa dla mnie (GNU bash w wersji 4.2.46 i 4.0.33 (i to samo zachowanie 2.05b.0, ale nocasematch nie jest zaimplementowany)) nawet przy użyciu
shopt -u nocasematch;
. Wyłączenie tej opcji nocasematch powoduje, że [["fooBaR" == "FOObar"]] pasuje do OK ALE dziwnie wewnątrz skrzynki [bz] są niepoprawnie dopasowane do [AZ] Bash jest zdezorientowany podwójnie ujemnym („niepokojącym nocasematch”)! :-)źródło
word="Hi All"
podobnie jak w innych przykładach, toha
niehi all
. Działa tylko w przypadku wielkich liter i pomija już małe litery.tr
iawk
przykłady są określone w standardzie POSIX.tr '[:upper:]' '[:lower:]'
użyje bieżących ustawień narodowych do określenia odpowiedników wielkich / małych liter, więc będzie działać z ustawieniami narodowymi, które używają liter ze znakami diakrytycznymi.b="$(echo $a | tr '[A-Z]' '[a-z]')"
W Bash 4:
Na małe litery
Do wielkich liter
Przełącz (nieudokumentowane, ale opcjonalnie konfigurowalne w czasie kompilacji)
Wielkie litery (nieudokumentowane, ale opcjonalnie konfigurowalne w czasie kompilacji)
Tytuł sprawy:
Aby wyłączyć
declare
atrybut, użyj+
. Na przykładdeclare +c string
. Wpływa to na kolejne przypisania, a nie na bieżącą wartość.Te
declare
opcje zmienić atrybut zmiennej, ale nie zawartość. Ponowne przypisania w moich przykładach aktualizują zawartość, aby pokazać zmiany.Edytować:
Dodano „przełącz pierwszy znak po słowie” (
${var~}
) zgodnie z sugestią ghostdog74 .Edycja: Poprawiono zachowanie tyldy, aby pasowało do Bash 4.3.
źródło
string="łódź"; echo ${string~~}
„ŁÓDŹ”, aleecho ${string^^}
zwróci „łóDź”. Nawet wLC_ALL=pl_PL.utf-8
. To używa bash 4.2.24.en_US.UTF-8
. To błąd i zgłosiłem go.echo "$string" | tr '[:lower:]' '[:upper:]'
. Prawdopodobnie wykaże tę samą awarię. Tak więc problem przynajmniej częściowo nie dotyczy Basha.źródło
tr
nie działa dla mnie dla znaków spoza ACII. Mam prawidłowy zestaw ustawień regionalnych i wygenerowane pliki ustawień narodowych. Masz pojęcie, co mogę zrobić źle?[:upper:]
potrzebnytr :
AWK :
sed :
źródło
a="$(tr [A-Z] [a-z] <<< "$a")"
wygląda dla mnie najłatwiej. Nadal jestem początkującym ...sed
rozwiązanie; Pracowałem w środowisku, które z jakiegoś powodu nie ma,tr
ale jeszcze nie znalazłem systemu bezsed
, a poza tym dużo czasu chcę to zrobić. Właśnie zrobiłem coś innego,sed
więc mogę połączyć polecenia razem w jedną (długą) instrukcję.tr [A-Z] [a-z] A
powłoce może wykonać rozszerzenie nazwy pliku, jeśli istnieją nazwy plików składające się z jednej litery lub ustawiono nullgob .tr "[A-Z]" "[a-z]" A
będzie się zachowywał poprawnie.sed
tr [A-Z] [a-z]
jest nieprawidłowy w prawie wszystkich lokalizacjach. na przykład wen-US
ustawieniach regionalnychA-Z
jest faktycznie interwałAaBbCcDdEeFfGgHh...XxYyZ
.Wiem, że to stary post, ale podałem tę odpowiedź dla innej witryny, więc pomyślałem, że opublikuję ją tutaj:
GÓRNA -> dolna : użyj Pythona:
Lub Ruby:
Lub Perl (prawdopodobnie mój ulubiony):
Lub PHP:
Lub Awk:
Lub Sed:
Lub Bash 4:
Lub NodeJS, jeśli go masz (i jesteś trochę szalony ...):
Możesz także użyć
dd
(ale nie chciałbym!):niższe -> GÓRNE :
użyj python:
Lub Ruby:
Lub Perl (prawdopodobnie mój ulubiony):
Lub PHP:
Lub Awk:
Lub Sed:
Lub Bash 4:
Lub NodeJS, jeśli go masz (i jesteś trochę szalony ...):
Możesz także użyć
dd
(ale nie chciałbym!):Także kiedy mówisz „shell”, zakładam, że masz na myśli,
bash
ale jeśli możesz użyć,zsh
jest to tak proste jakdla małych liter i
dla wielkich liter.
źródło
a
zawiera pojedynczy cytat, masz nie tylko zepsute zachowanie, ale poważny problem z bezpieczeństwem.W Zsh:
Uwielbiam Zsh!
źródło
echo ${(C)a} #Upcase the first char only
Za pomocą GNU
sed
:Przykład:
źródło
Pre Bash 4.0
Bash Opuść wielkość liter ciągu i przypisz do zmiennej
źródło
echo
i rur: użyj$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
Dla standardowej powłoki (bez bashism) używającej tylko wbudowanych poleceń:
I dla wielkich liter:
źródło
${var:1:1}
są Bashizmem.W bash 4 możesz użyć składu
Przykład:
źródło
Możesz tego spróbować
ref: http://wiki.workassis.com/shell-script-convert-text-to-lowercase-and-uppercase/
źródło
Wyrażenie regularne
Chciałbym podziękować za polecenie, którym chcę się podzielić, ale prawda jest taka, że uzyskałem je na własny użytek ze strony http://commandlinefu.com . Ma tę zaletę, że jeśli
cd
przejdziesz do dowolnego katalogu w swoim własnym folderze domowym, to znaczy zmieni wszystkie pliki i foldery na małe litery rekurencyjnie, używaj ostrożnie. Jest to doskonała poprawka do wiersza poleceń i szczególnie przydatna w przypadku wielu albumów przechowywanych na dysku.Możesz podać katalog zamiast kropki (.) Po znalezieniu, który oznacza bieżący katalog lub pełną ścieżkę.
Mam nadzieję, że to rozwiązanie okaże się użyteczne. Jedyną rzeczą, której nie robi to polecenie, jest zastąpienie spacji znakami podkreślenia - no cóż, może innym razem.
źródło
prename
odperl
:dpkg -S "$(readlink -e /usr/bin/rename)"
dajeperl: /usr/bin/prename
Wiele odpowiedzi za pomocą zewnętrznych programów, które tak naprawdę nie są używane
Bash
.Jeśli wiesz, że będziesz mieć dostępną wersję Bash4, powinieneś po prostu użyć
${VAR,,}
notacji (jest to łatwe i fajne). W przypadku wersji Bash przed 4 (na moim komputerze Mac nadal jest używana wersja Bash 3.2). Użyłem poprawionej wersji odpowiedzi @ ghostdog74, aby stworzyć bardziej przenośną wersję.Możesz zadzwonić
lowercase 'my STRING'
i uzyskać małą wersję. Czytam komentarze na temat ustawiania wyniku na var, ale to nie jest tak naprawdę przenośneBash
, ponieważ nie możemy zwrócić ciągów. Drukowanie to najlepsze rozwiązanie. Łatwy do uchwycenia za pomocą czegoś takiegovar="$(lowercase $str)"
.Jak to działa
Działa to poprzez uzyskanie reprezentacji liczb całkowitych ASCII każdego znaku za pomocą,
printf
a następnieadding 32
ifupper-to->lower
lubsubtracting 32
iflower-to->upper
. Następnie użyjprintf
ponownie, aby przekonwertować liczbę z powrotem na znak. Od'A' -to-> 'a'
mamy różnicę 32 znaków.Za pomocą
printf
wyjaśnienia:97 - 65 = 32
A to jest wersja robocza z przykładami.
Zwróć uwagę na komentarze w kodzie, ponieważ wyjaśniają wiele rzeczy:
A wyniki po uruchomieniu tego:
Powinno to jednak działać tylko w przypadku znaków ASCII .
Dla mnie jest w porządku, ponieważ wiem, że przekażę mu tylko znaki ASCII.
Używam tego na przykład do niektórych opcji CLI bez rozróżniania wielkości liter.
źródło
Konwersja jest wykonywana tylko dla alfabetów. Więc to powinno działać dobrze.
Koncentruję się na konwersji alfabetów między az z wielkich na małe litery. Wszelkie inne postacie powinny być po prostu wydrukowane w stdout, ponieważ jest ...
Konwertuje cały tekst w ścieżce / na / plik / nazwę pliku z zakresu az na AZ
Do konwersji małych i wielkich liter
Do konwersji z wielkich na małe litery
Na przykład,
Nazwa pliku:
zostanie przekonwertowany na:
Przykład 2:
Przykład 3:
źródło
Jeśli używasz v4, jest to włączone . Jeśli nie, oto proste, szeroko stosowane rozwiązanie. Inne odpowiedzi (i komentarze) w tym wątku były bardzo pomocne w tworzeniu poniższego kodu.
Uwagi:
a="Hi All"
a następnie:lcase a
zrobi to samo, co:a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
zamiast${!1}
pozwala na to, aby działało nawet wtedy, gdy ciąg zawiera cudzysłowy.źródło
W przypadku wersji Bash wcześniejszych niż 4.0 ta wersja powinna być najszybsza (ponieważ nie rozwidla / nie wykonuje żadnych poleceń):
Odpowiedź technozaura też miała potencjał, choć dla mnie działała poprawnie.
źródło
Pomimo wieku tego pytania i podobnego do odpowiedzi udzielonej przez technozaura . Trudno mi było znaleźć rozwiązanie, które byłoby przenośne na większości platform (których używam), a także na starszych wersjach bash. Byłem również sfrustrowany tablicami, funkcjami i wykorzystaniem wydruków, echa i plików tymczasowych do wyszukiwania trywialnych zmiennych. Działa to dla mnie bardzo dobrze. Moje główne środowiska testowe to:
Prosty styl C dla pętli do iteracji po łańcuchach. W poniższej linii, jeśli nie widziałeś czegoś takiego wcześniej, tutaj się tego nauczyłem . W tym przypadku wiersz sprawdza, czy znak $ {input: $ i: 1} (małe litery) istnieje w danych wejściowych, a jeśli tak, to zastępuje go danym znakiem $ {ucs: $ j: 1} (wielkie litery) i przechowuje go z powrotem do wejścia.
źródło
Jest to znacznie szybsza odmiana podejścia JaredTS486, który wykorzystuje natywne możliwości Bash (w tym wersje Bash <4.0) do optymalizacji swojego podejścia.
Zmierzyłem czas 1000 iteracji tego podejścia dla małego ciągu (25 znaków) i większego ciągu (445 znaków), zarówno dla konwersji małych jak i wielkich liter. Ponieważ ciągi testowe są przeważnie pisane małymi literami, konwersje na małe litery są na ogół szybsze niż na wielkie.
Porównałem swoje podejście z kilkoma innymi odpowiedziami na tej stronie, które są kompatybilne z Bash 3.2. Moje podejście jest znacznie bardziej wydajne niż większość podejść tutaj udokumentowanych i jest nawet szybsze niż
tr
w kilku przypadkach.Oto wyniki synchronizacji dla 1000 iteracji po 25 znaków:
tr
małe litery; 3,81s dla wielkich literWyniki czasowe dla 1000 iteracji 445 znaków (składających się z wiersza „Robin” Wittera Bynnera):
tr
małe litery; 4s dla wielkich literRozwiązanie:
Podejście jest proste: podczas gdy w ciągu wejściowym znajdują się pozostałe wielkie litery, znajdź następną i zamień wszystkie wystąpienia tej litery na jej małą literę. Powtarzaj, aż wszystkie wielkie litery zostaną zastąpione.
Niektóre cechy wydajności mojego rozwiązania:
UCS
iLCS
może być uzupełniony o dodatkowe postacieźródło
Aby zapisać przekształcony ciąg w zmienną. Następujące pracował dla mnie -
$SOURCE_NAME
do$TARGET_NAME
źródło
Prosta droga
źródło