Удалить самую длинную последовательность символов с начала или с конца.

Удалить самую длинную последовательность символов с начала или с конца.

Например, строка имеет вид: 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*

Первоначальная повторяющаяся строка была правильно удалена, но следующие четыре обратных слеша были преобразованы всего в два.

Связанный контент