Например, строка имеет вид: aaaaabbaabaabbaa. Я хочу обрезать ее так, чтобы удалить все «a» с начала до «b», поэтому результат должен быть bbaabaabbaa.
решение1
Посмотрите разделыРасширение параметровиСопоставление с образцомв man 1 bash
:
$ shopt -s extglob # enable extended glob operators
$ s=aaaaabbaabaabbaa
$ echo "${s##*(a)}"
bbaabaabbaa
$ s=bananasssssssss
$ echo "${s%%*(s)}"
banana
решение2
С GNU sed
:
sed -e 's/^\(.\)\1\{1,\}//'
который сопоставляет и удаляет любой символ, повторяющийся хотя бы один раз в начале строки. Он использует ^\(.\)
для сопоставления первый символ, а затем \1\{1,\}
для сопоставления 1 или более с обратной ссылкой на это сопоставление.
Если вы хотите сопоставить только 1 или более повторений первого символа, вы можете использовать просто sed -e 's/^\(.\)\1\+//'
, но \{1,\}
форму можно легко изменить для 2 или более или 3 или более повторений и т. д., если это необходимо.
решение3
Всего две строки:
$ a="aaaaabbaabaabbaaddd"
$ echo "${a#"${a%%[^"${a:0:1}"]*}"}"
bbaabaabbaaddd
Действие пояснено:
"${a:0:1}" ## Select the first char of $a: ='a'
[^ ]* ## All chars not 'a' from the end. ='bbaabaabbaaddd'
"${a%% }" ## Remove 'bbaabaabbaaddd' from the end of $a. ='aaaaa'
echo "${a# }" ## Remove 'aaaaa' from start of $a and echo it.
(-)Оба расширения требуют кавычек для корректной обработки * и /. Проблема в том, что обратные кавычки обычно обрабатываются неправильно:
a="\\\\*\\\\*****vdf*"; echo "${a#"${a%%[^"${a:0:1}"]*}"}"
Будет напечатано:
*\\*****vdf*
Первоначальная повторяющаяся строка была правильно удалена, но следующие четыре обратных слеша были преобразованы всего в два.