Elimine la serie consecutiva más larga de caracteres del frente o del reverso

Elimine la serie consecutiva más larga de caracteres del frente o del reverso

Por ejemplo, una cadena tiene: aaaaabbaabaabbaa. Quiero recortarla para que borre cada "a" desde el frente hasta la "b", por lo que el resultado debe ser bbaabaabbaa.

Respuesta1

Echa un vistazo a las secciones.Expansión de parámetrosyLa coincidencia de patronesen man 1 bash:

$ shopt -s extglob # enable extended glob operators
$ s=aaaaabbaabaabbaa
$ echo "${s##*(a)}"
bbaabaabbaa

$ s=bananasssssssss
$ echo "${s%%*(s)}"
banana

Respuesta2

Con GNU sed:

sed -e 's/^\(.\)\1\{1,\}//'

que coincide y elimina cualquier carácter que se repita al menos una vez al principio de una línea. se utiliza ^\(.\)para hacer coincidir el primer carácter, luego \1\{1,\}para hacer coincidir 1 o más con una referencia inversa a esa coincidencia.

Si solo desea hacer coincidir 1 o más repeticiones del primer carácter, puede usar solo sed -e 's/^\(.\)\1\+//', pero el \{1,\}formulario se puede modificar fácilmente para 2 o más o 3 o más, etc., si es necesario.

Respuesta3

Sólo dos líneas:

$ a="aaaaabbaabaabbaaddd" 
$ echo "${a#"${a%%[^"${a:0:1}"]*}"}"
bbaabaabbaaddd

Acción explicada:

                  "${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.

(-)Ambas expansiones necesitan comillas para tratar correctamente * y /. Todavía existe el problema de que las comillas invertidas normalmente se procesan incorrectamente:

a="\\\\*\\\\*****vdf*"; echo "${a#"${a%%[^"${a:0:1}"]*}"}"

Imprimirá:

*\\*****vdf*

La cadena repetida inicial se eliminó correctamente, pero las siguientes cuatro barras invertidas se transformaron en solo dos.

información relacionada