¿Cómo busco subcadenas en Bash?

3

Quiero averiguar y mostrar la cantidad total de subcadenas TTT encontradas en las primeras 2,000 líneas en el archivo.

Había estado usando grep hasta que lo probé, y me di cuenta de que no identifica subcadenas.

sin nombre
fuente

Respuestas:

1

Si está buscando la aparición de 3 caracteres "T" consecutivos en un archivo, puede hacerlo con grep. ¿Qué intentaste que no funcionó? Y, si solo desea verificar las primeras 2.000 líneas del archivo, puede canalizar la salida del comando head en grep. Por ejemplo, head -n 2000 somefile.txt | grep "TTT"si desea un recuento de las líneas en el archivo que contiene "TTT", puede usar lo siguiente:

head -n 2000 somefile.txt | grep -c "TTT"

Si algunas líneas pueden tener múltiples ocurrencias y desea contar todas las ocurrencias en lugar de solo la cantidad de líneas que contienen "TTT", use la -oopción para grep , que mostrará cada ocurrencia en una línea separada y luego canalizará la salida en el wc comando, que luego mostrará un recuento de todas las apariciones de "TTT" dentro de las primeras 2000 líneas del archivo:

head -n 2000 somefile.txt | grep -o "TTT" | wc -l

punto de luna
fuente
1
Hola y gracias por tu respuesta! Originalmente había usado el mismo comando, sin embargo, cuando probé grep con un archivo mucho más corto que contenía algo como: JKHFSDTTTJSDJHTTTTTKSJTIITTT, no reconoce las tres subcadenas de TTT en TTTTT, resaltará la primera subcadena de 'TTT'TT y no tendrá en cuenta Los últimos dos. : /
noname
0

Explicación

Normalmente, la búsqueda TTT(3 T's) en TTTTTT(6 T's) produce solo 2 coincidencias porque la búsqueda de la siguiente coincidencia se realiza justo después de encontrar la coincidencia anterior.

Trataré de ilustrar:

TTTTTT
^ set starting position

TTTTTT
‾‾‾  found a match for TTT

TTTTTT
‾‾‾^ set next starting position

TTTTTT
   ‾‾‾  found a match for TTT

TTTTTT
      ^ end of stream

Solución

Si desea considerar TTTTTTcomo cuatro instancias de TTT, entonces le sugiero que coincida con un solo carácter y luego use lookaround para completar su patrón de coincidencia.

Usaré un lookahead en mi solución:

head -2000 file | /usr/gnu/bin/grep -P -o 'T(?=TT)' | wc -l

Explicaciones para la grepparte:

  • Use una grepque admita la expresión regular de Perl para usar lookahead; en mi sistema necesito especificar eso para/usr/gnu/bin/grep
  • -P para activar el modo de expresión regular de Perl
  • -opara mostrar cada aparición en una línea separada para permitir wc -lcontar cada coincidencia
  • 'T(?=TT)'es una expresión regular para coincidir Tque es seguida por TT(usando una búsqueda anticipada); Después de encontrar una coincidencia, el motor de expresión regular comenzará en el segundo T para tratar de encontrar la siguiente coincidencia, permitiendo que ese segundo T sea ​​parte de la siguiente coincidencia si se ajusta al patrón.

Ejemplo

Usando su cadena de muestra del comentario:

  • JKHFSDTTTJSDJHTTTTTKSJTIITTT

y procesarlo con la expresión regular anterior:

echo 'JKHFSDTTTJSDJHTTTTTKSJTIITTT' | /usr/gnu/bin/grep -P --color=always 'T(?=TT)'

Producirá:

  • JKHFSD T TTJSDJH TTT TTKSJTII T TT (es decir, resaltará 5 T)

lo que significa:

  • encuentra 5 coincidencias :)

Ilustración:

JKHFSDTTTJSDJHTTTTTKSJTIITTT
^ set starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
      ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
              ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
               ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
                ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
                         ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
                            ^ end of stream
aff
fuente