¿Encontrar un archivo de texto que contenga un texto determinado ignorando nuevas líneas y espacios?

¿Encontrar un archivo de texto que contenga un texto determinado ignorando nuevas líneas y espacios?

Tengo una cadena como: "thisissometext". Quiero encontrar todos los archivos de texto dentro de un directorio determinado (recursivamente) que contengan esta cadena, o cualquier variación de la misma con espacios en blanco y/o nuevas líneas en el medio. Por ejemplo, un archivo de texto que contenga "this is sometext"o "this\n issometext"debería "this\n isso metext" aparecer en la búsqueda. ¿Cómo puedo hacer esto?

Respuesta1

Con las versiones más nuevas de GNU grep(que tienen la -zopción) puedes usar este delineador:

find . -type f -exec grep -lz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' {} +

Teniendo en cuenta que los espacios en blanco solo pueden aparecer entre las palabras.

Si solo desea buscar todos los archivos de forma recursiva a partir del directorio actual, no necesita find, simplemente puede usar grep -r(recursivo). findse puede utilizar para ser selectivo en los archivos a buscar, por ejemplo, elegir archivos de qué directorio excluir. Tan simplemente:

grep -rlz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' .
  • El truco principal aquí es -zque tratará cada línea del flujo de entrada terminada en ASCII NUL en lugar de una nueva línea, como resultado podemos hacer coincidir nuevas líneas utilizando los métodos habituales.

  • [[:space:]]El patrón de clase de caracteres indica cualquier carácter de espacio en blanco, incluido espacio, tabulación, CR, LF, etc. Por lo tanto, podemos usarlo para hacer coincidir todos los caracteres de espacio en blanco que pueden aparecer entre las palabras.

  • grep -limprimirá solo los nombres de archivos que tengan alguno de los patrones deseados. Si también desea imprimir las coincidencias, utilice -Hen lugar de -l.

Por otro lado, si los espacios en blanco pueden aparecer en cualquier lugar en lugar de las palabras, esto perdería su buena apariencia:

grep -rlz
't[[:space:]]*h[[:space:]]*i[[:space:]]*s[[:space:]]*i[[:space:]]*\
s[[:space:]]*s[[:space:]]*o[[:space:]]*m[[:space:]]*e[[:space:]]*\
t[[:space:]]*e[[:space:]]*x[[:space:]]*t' .

Con -Pla opción (PCRE) puedes reemplazarla [[:space:]]con \s(esto se vería mucho mejor):

grep -rlzP 't\s*h\s*i\s*s\s*i\s*s\s*s\s*o\s*m\s*e\s*\
t\s*e\s*x\s*t' .

Usar la sugerencia de @steeldriver para sedgenerar el patrón para nosotros sería la mejor opción:

grep -rlzP "$(sed 's/./\\s*&/2g' <<< "thisissometext")" .

Respuesta2

Puede eliminar todos los espacios en blanco y guardarlos:

tr -d '[[:space:]]' < foo | grep thisissometext

Extensión:

find . -type f -exec bash -c 'for i; do tr -d "[[:space:]]" < "$i" | grep -q thisissometext && printf "%s\n" "$i"; done' _ {} +

El bashcomando, ampliado:

for i
do
    tr -d "[[:space:]]" < "$i" | 
      grep -q thisissometext && 
      printf "%s\n" "$i"
done

Esto recorre todos los argumentos y utiliza la prueba anterior.

Respuesta3

El siguiente código busca archivos en un directorio de forma recursiva, elimina todas las apariciones de " "y "\n". Si la cadena existe en el texto restante, hay una coincidencia. Esto implica que los espacios/nuevas líneas pueden estar encualquierposición en la cadena dentro de su(s) archivo(s).

Que hace

Si encuentra archivos coincidentes, se imprimirán en la terminal, incluidas sus rutas, como:

/home/jacob/Bureaublad/testmap/test2.txt
/home/jacob/Bureaublad/testmap/Naamloze map 2/test1.txt

El try/except lo incorporé para evitar que el script se rompa si se ejecuta en un archivo ilegible.

La secuencia de comandos

#!/usr/bin/env python3
import os
import sys

s = sys.argv[2]
for root, dirs, files in os.walk(sys.argv[1]):
    for file in files:
        file = root+"/"+file
        try:
            if s in open(file).read().replace(" ", "").replace("\n",""):
                print(file)
        except:
            pass

Cómo utilizar

  1. Copie el script en un archivo vacío, guárdelo comofind_string.py
  2. Ejecútelo con el directorio y la cadena como argumentos:

    python3 /path/to/find_string.py <directory> <string_to_find>
    

    Si la cadena o el directorio contienen espacios, utilice comillas:

    python3 /path/to/find_string.py '<directory>' '<string_to_find>'
    

Nota

El script, tal como está, busca archivos con la cadena, ya sea con espacios en blanco o nuevas líneas. Se puede expandir con otros caracteres/cadenas (por ejemplo, tabulaciones) en la línea:

if s in open(file).read().replace(" ", "").replace("\n",""):

Respuesta4

Podrías usar grep -i --recursive 'word1\|word2' *y awk '/word1/,/word2/'puedes usar para lidiar con la nueva línea

ingrese la descripción de la imagen aquí

información relacionada