Czasem zdarza się, że mamy ogromną ilość plików zapisanych WIELKIMI literami, a z jakiegoś powodu chcemy zamienić je na małe. Jeżeli tych plików jest kilka, możemy zmienić ich nazwy ręcznie. Ale co będzie jeśli musimy zmienić ponad 1000 plików, które są zdjęciami z wakacji? Z pomocą przyjdzie nam polecenie tr
. Jest to narzędzie, za pomocą którego można zmieniać i usuwać znaki. Polecenie to czyta ze standardowego wejścia i wynik wypisuje na standardowe wyjście.
Zaczynając przygodę z poleceniem tr
poznajmy jego podstawowe funkcje. Wydając polecenie: tr abc xyz
zamienimy każdy nak występujący na i-tym miejscu w abc
jest zastępowany znakiem występującym na i-tym miejscu w xyz
. Zatem każde a na wejściu zamieni się na x, b na y i c na z. Zatem sprawdźmy, czy to prawda:
paszczak000@hell:~$ echo Ala ma kota i lubi go całować | tr abc xyz Alx mx kotx i luyi go zxłowxć
Jak widać polecenie tr
poprawnie zamieniło znaki. Ale to nie wszystko. Możemy wykorzystać tr
do usuwania znaków podanych na wejściu. Do tego służy parametr -d
. Wydając polecenie tr -d abc
skasujemy wszystkie znaki abc
jakie znajdą się na wejściu. Jeśli dodamy parametr -c
, spowodujemy, że usuniemy wszystkie znaki, które nie podaliśmy w parametrze. Przykład:
paszczak000@hell:~$ echo Ala ma kota i lubi go całować | tr -d a Al m kot i lubi go cłowć paszczak000@hell:~$ echo Mam na imie Piotrek. Mój numer to telefonu to 948-234-446-32 | tr -cd 0123456789 94823444632
Jak widać w pierwszym przykładzie usunęliśmy wszystkie literki a
. Natomiast w drugim chcieliśmy wyciągnąć sam numer telefonu z ciągu znaków. tr
usunął wszystkie znaki poza cyframi (0123456789).
Znając podstawowe funkcje polecenia, możemy przystąpić do próby zmiany wielkich liter na małe. W Internecie dostępne jest wiele tego typu przykładów, dlatego przyjrzymy im się z bliska. Najprostszą metodą jest wykorzystanie skryptu:
for file in * ; do mv "$file" `echo "$file" | tr '[A-Z]' '[a-z]'` done
Pętla for
pobierze nam wszystkie pliki w danym katalogu, po czym poleceniem mv
oraz tr
zmienimy im nazwę. W nawiasach kwadratowych podany jest zakres znaków jakie mają zostać zamienione. Możemy delikatnie zmodyfikować skrypt i wykorzystać klasy znaków dla polecenia tr
:
for file in * do mv $file `echo $file | tr [:upper:] [:lower:]` done
W tym wypadku wykorzystując klasy upper
i lower
Wykorzystując klasy możemy określić jakie zakresy znaków mają być brane pod uwagę. Mamy do dyspozycji:
- alnum – znaki alfanumeryczne
- alpha – litery
- cntrl – znaki kontrolne
- digit – cyfry
- graph – znaki graficzne, bez spacji
- lower – małe litery
- print – znaki pisarskie w tym spacja
- punct – znaki interpunkcyjne
- space – spacje, białe znaki
- upper – wielkie litery
- xdigit – znaki hexadecymalne
Taką samą operację (zmiana wielkich liter na małe) możemy wykonać z wykorzystaniem Perla w skrypcie:
for file in `ls -1|perl -ne 'print "$_" if (/[A-Z]/);'` do mv ${file} `echo ${file}|perl -ne 'chomp;print "$_" if (tr/A-Z/a-z/);'`; done
W Internecie dostępne są również inne modyfikacje powyższych skryptów. Jedną z nich jest kod napisany przez Johna Dubois, a następnie zmodyfikowany przez Chet Ramey:
#!/bin/bash # # Changes every filename in working directory to all lowercase. # # Inspired by a script of John Dubois, #+ which was translated into Bash by Chet Ramey, #+ and considerably simplified by the author of the ABS Guide. for filename in * # Traverse all files in directory. do fname=`basename $filename` n=`echo $fname | tr A-Z a-z` # Change name to lowercase. if [ "$fname" != "$n" ] # Rename only files not already lowercase. then mv $fname $n fi done exit $?
Niestety skrypt ten nie poradzi sobie z plikami, które zawierają różnego rodzaju białe znaki oraz znak nowej linii. Stephane Chazelas zaproponował następujące rozwiązanie:
# The above script will not work on filenames containing blanks or newlines. # Stephane Chazelas therefore suggests the following alternative: for filename in * # Not necessary to use basename, # since "*" wont return any file containing "/". do n=`echo "$filename/" | tr '[:upper:]' '[:lower:]'` # POSIX char set notation. # Slash added so that trailing newlines are not # removed by command substitution. # Variable substitution: n=${n%/} # Removes trailing slash, added above, from filename. [[ $filename == $n ]] || mv "$filename" "$n" # Checks if filename already lowercase. done exit $?
Polecenie tr
jest bardzo przydatne jeśli chcemy usunąć z nazw naszych plików zbędne znaki lub ustandaryzować ich wielkość. Więcej informacji na temat tr
, dostępne jest w manualu.
[…] nazwy na małe literki. Do tego celu posłuży nam polecenie tr, które zostało opisane w artykule Masowa zmiana nazw plików pisanych WIELKIMI literami na małe. Wykorzystując jedną ze znanych nam metod przystępujemy do zmiany nazw […]
postanowilem zmodyfikowac nieco powyzszy plik i pozbawia on znaki diaktryczne i spacje z plikow – ja stosuje to do plikow uzytkownikow ktorzy trzymaja swoje dane na sambie i zapominaja ze zaleta jest nie stosowac powyzszych w nazwach plikow:
<pre>#!/bin/bash
# USUNIECIE POLSKICH LITER
for filename in *
do n=`echo "$filename/" | tr [:blank:] _ | tr "241" "A"|tr "261" "a"|tr "246" "S"|tr "266" "s"|tr "257" "Z"|tr "277" "z"|tr "254" "Z"|tr "274" "z"|tr "306" "C"|tr "346" "c"|tr "323" "O"|tr "363" "o"|tr "243" "L"|tr "263" "l"|tr "321" "N"|tr "361" "n"|tr "312" "E"|tr "352" "e"
`
n=${n%/}
echo "JEST :> " $filename "ZMIENIAM NA :>" $n
#sleep 1
[[ $filename == $n ]] || mv "$filename" "$n"
done
exit $?</pre>
[…] nazwy na małe literki. Do tego celu posłuży nam polecenie tr, które zostało opisane w artykule Masowa zmiana nazw plików pisanych WIELKIMI literami na małe. Wykorzystując jedną ze znanych nam metod przystępujemy do zmiany nazw […]
[…] źródło: https://osworld.pl/masowa-zmiana-nazw-plikow-pisanych-wielkimi-literami-na-male/ […]