Bash Site about Linux


Вернуться к оглавлению

02.02.2013

Разложение строк средствами Bash в примерах (parameter expansions)


(Использовались материалы [ 1] [ 2] и [ 3])


Для работы над строками средствами Bash используются параметры разложения (parameter expansions) Описание этого принципа можно найти в man Bash в пункте 3.5.3 Shell Parameter Expansion.
Описание трудновато для понимания. Намного проще понять принцип работы на примерах.


1. Удаление символов в начале или в конце строки

Любой одиночный символ обозначается как "?"

Зададим переменную STRING:

[shonty@~]$ STRING=aabbcc
[shonty@~]$ echo ${STRING}
aabbcc
Для удаления символов в начале строки используем команды:
[shonty@~]$ echo ${STRING#?}
abbcc
[shonty@~]$ echo ${STRING#???}
bcc
для удаления символов в конце строки:
[shonty@~]$ echo ${STRING%?}
aabbc
[shonty@~]$ echo ${STRING%???}
aab
Что бы запомнить, когда применять знак #, а когда % используют вот такой оригинальный способ:
Символы #$% располагаются на клавиатуре последовательно и:
# - слева от $, означает с начала строки
% - справа от $, означает до конца строки



2. Удаление регулярных выражений в начале или в конце строки

Регулярные выражения (regular expressions или RegExp, regex) - это строка-шаблоном или «маска» задающая правило поиска.


Снова зададим переменную STRING:

[shonty@~]$ STRING=GNULinux
[shonty@~]$ echo ${STRING}
GNULinux
удаляем регулярное выражение в начале строки:
[shonty@~]$ echo ${STRING#GNU}
Linux
удаляем регулярное выражение в конце строки:
[shonty@~]$ echo ${STRING%Linux}
GNU
Теперь тоже самое, но используя "*" (астериск)
удаляем регулярное выражение в начале строки (GNU=*U):
[shonty@~]$ echo ${STRING#*U}
Linux
удаляем регулярное выражение в конце строки (Linux=L*):
[shonty@~]$ echo ${STRING%L*}
GNU

Использование регулярных выражений может быть скомбинировано с "?" (знаком любого символа) (Linux=L*=??n*):

[shonty@~]$ echo ${STRING%??n*}
GNU


3. Использование сдвоенных ## и %%

Если при удалении из строки регулярных выражений (*regex или regex*), при использовании "#" и "%" с "*" - удаление идёт до первого вхождения регулярного выражения, то при использовании сдвоенных "##" и "%%" - до последнего:

И снова зададим переменную STRING:

[shonty@~]$ STRING=abcdcba
[shonty@~]$ echo ${STRING}
abcdcba
STRING=abcdcba
${STRING#*c}     abcdcba
${STRING##*c}    abcdcba
${STRING%c*}     abcdcba
${STRING%%c*}    abcdcba
[shonty@~]$ echo ${STRING#*c}
dcba
[shonty@~]$ echo ${STRING##*c}
ba
[shonty@~]$ echo ${STRING%c*}
abcd
[shonty@~]$ echo ${STRING%%c*}
ab


4. Поиск и замена

${STRING/<шаблон_поиска>/<замена>} -замена первого вхождения
${STRING//<шаблон_поиска>/<замена>} -глобальная замена
[shonty@~]$ STRING="abracadabra"
[shonty@~]$ echo "${STRING/a/O}"
Obracadabra
[shonty@~]$ echo "${STRING//a/O}"
ObrOcOdObrO
[shonty@~]$ echo "${STRING/#a/O}"
Obracadabra
[shonty@~]$ echo "${STRING/%a/O}"
abracadabrO
[shonty@~]$ echo "${STRING/a/}"
bracadabra
[shonty@~]$ echo "${STRING//a/}"
brcdbr


5. Извлечение подстроки используя смещение и длину ${STRING:offset:length}


${STRING:offset:length}

offset -смещение от края строки
length -длина подстроки

5.1 Смещение при положительных значениях <offset>

При положительных значениях смещения первому символу строки соответствует значение "0".

Если <length> не задана, то длина подстроки автоматически продляется до конца.

Примеры с положительными значениями <offset>:
[shonty@~]$ STRING="Debian Gentoo RedHat"
[shonty@~]$ echo ${STRING:0:6}
Debian
[shonty@~]$ echo ${STRING:14}
RedHat
[shonty@~]$ echo ${STRING:7:6}
Gentoo

5.2 Смещение при отрицательных значениях <offset>

При отрицательных значениях <offset> отсчёт ведётся от конца строки, а последнему символу строки соответствует значение <offset> равное "-1".

Для записи отрицательного смещения между двоеточием и знаком минус нужно оставлять пробел или брать отрицательное значение в круглые скобки.

Если <length> не задана, то длина подстроки автоматически продляется до конца.

Примеры с отрицательными значениями <offset>:
[shonty@~]$ STRING="Debian Gentoo RedHat"
[shonty@~]$ echo ${STRING: -6}
RedHat
[shonty@~]$ echo ${STRING:(-6)}
RedHat
[shonty@~]$ echo ${STRING:(-6):3}
Red
[shonty@~]$ echo ${STRING:(-6):10}  # длина превышает смещение
RedHat

5.3 Отрицательные значения <length>.

Если <length> принимает отрицательное значение, то она работает как смещение от конца строки. Результатом будет подстрока между первым и вторым смещениями:

[shonty@~]$ STRING="Debian Gentoo RedHat"
[shonty@~]$ echo ${STRING:7:-7}
Gentoo
[shonty@~]$ echo ${STRING:(-14):-7}
Gentoo


Как всё это применить на практике:

Ниже представлены различные варианты кода для смены расширения с *.wav на *.mp3 при пакетном перекодировании аудио файлов:
for i in *.wav; do lame "$i" "${i%???}mp3"; done;
for i in *.wav; do lame "$i" "${i%wav}mp3"; done;
for i in *.wav; do lame "$i" "${i%.*}.mp3"; done;
for i in *.wav; do lame "$i" "${i/wav/mp3}"; done;
for i in *.wav; do lame "$i" "${i:0:-3}mp3"; done;


6. Подсчёт количества символов в строке ${#STRING}

[shonty@~]$ STRING="Подсчёт количества символов в строке"
[shonty@~]$ echo ${#STRING}
36

Узнать количество символов в файле:
[shonty@~]$ ARRAY=(`cat file.html`)
[shonty@~]$ echo ${#ARRAY[@]}
1158

Здесь нужно отметить, что файл читается не просто в переменную, а в массив, так как он состоит из нескольких строк. Поэтому для правильного подсчёта необходимо ставить [@]. Если этого не сделать, то команда прочитает только первую строку из файла:

[shonty@~]$ ARRAY=(`cat file.html`)
[shonty@~]$ echo ${#ARRAY}
7
И правда, первая строка содержит лишь тег <html> и символ перевода строки виндовс (CR+LF) - и того 7 символов.

7. Изменение регистра символов


${STRING^} -переводит первый символ в верхний регистр
${STRING^^} -переводит все символы в верхний регистр
${STRING,} -переводит первый символ в нижний регистр
${STRING,,} -переводит все символы в нижний регистр
${STRING~} -инвертирует регистр первого символа
${STRING~~} -инвертирует регистр всех символов





Вернуться к оглавлению







Яндекс.Метрика
ВебСтолица.РУ: создай свой бесплатный сайт!  | Пожаловаться  
Движок: Amiro CMS