GNU/Linux >> Tutoriales Linux >  >> Linux

¿Buscar archivos de texto donde existen dos palabras diferentes (cualquier orden, cualquier línea)?

Estoy buscando una forma de buscar archivos donde existen dos instancias de palabras en el mismo archivo. He estado usando lo siguiente para realizar mis búsquedas hasta este momento:

find . -exec grep -l "FIND ME" {} ;

El problema con el que me encuentro es que si no hay exactamente un espacio entre "FIND" y "ME", el resultado de la búsqueda no arroja el archivo. ¿Cómo adapto la cadena de búsqueda anterior en la que las palabras "FIND" y "ME" existen en un archivo en lugar de "FIND ME"?

Estoy usando AIX.

Respuesta aceptada:

Con herramientas GNU:

find . -type f  -exec grep -lZ FIND {} + | xargs -r0 grep -l ME

Puedes hacer de manera estándar:

find . -type f -exec grep -q FIND {} ; -exec grep -l ME {} ;

Pero eso correría hasta dos grep s por archivo. Para evitar ejecutar tantos grep s y seguir siendo portátil y al mismo tiempo permitir cualquier carácter en los nombres de archivo, podría hacer:

convert_to_xargs() {
  sed "s/[[:blank:]"']/\\&/g" | awk '
    {
      if (NR > 1) {
        printf "%s", line
        if (!index($0, "//")) printf "\"
        print ""
      }
      line = $0
    }'
    END { print line }'
}

export LC_ALL=C
find .//. -type f |
  convert_to_xargs |
  xargs grep -l FIND |
  convert_to_xargs |
  xargs grep -l ME

La idea es convertir la salida de find en un formato adecuado para xargs (que espera un espacio en blanco (SPC/TAB/NL en el C configuración regional, YMMV en otras configuraciones regionales) lista separada de palabras donde las comillas simples, dobles y las barras diagonales inversas pueden escapar de los espacios en blanco y entre sí).

Por lo general, no puede posprocesar la salida de find -print , porque separa los nombres de archivo con un carácter de nueva línea y no escapa a los caracteres de nueva línea que se encuentran en los nombres de archivo. Por ejemplo, si vemos:

./a
./b

No tenemos forma de saber si se trata de un archivo llamado b en un directorio llamado a<NL>. o si son los dos archivos a y b en el directorio actual.

Usando .//. , porque // no puede aparecer de otra manera en una ruta de archivo como resultado de find (porque no existe un directorio con un nombre vacío y / no está permitido en un nombre de archivo), sabemos que si vemos una línea que contiene // , entonces esa es la primera línea de un nuevo nombre de archivo. Entonces podemos usar ese awk Comando para escapar todos los caracteres de nueva línea excepto aquellos que preceden a esas líneas.

Si tomamos el ejemplo anterior, find daría salida en el primer caso (un archivo):

.//a
./b

Cual awk escapa a:

.//a
./b

Así que xargs lo ve como un argumento. Y en el segundo caso (dos archivos):

.//a
.//b

¿Qué awk dejaría como está, así que xargs ve dos argumentos.

Relacionado:¿Tmux mouse-mode on no permite seleccionar texto con el mouse?

Necesitas el LC_ALL=C entonces sed , awk (y algunas implementaciones de xargs ) funcionan para secuencias arbitrarias de bytes (aunque no formen caracteres válidos en la configuración regional del usuario), para simplificar el espacio en blanco definición a solo SPC y TAB y para evitar problemas con diferentes interpretaciones de caracteres cuya codificación contiene la codificación de barra invertida por las diferentes utilidades.


Linux
  1. ¿Comparar dos columnas de diferentes archivos e imprimir si coincide?

  2. ¿Cómo buscar archivos por tamaño y extensión?

  3. Linux:¿dónde están los metadatos de los archivos PDF? ¿Puedo insertar metadatos en cualquier archivo PDF?

  4. ¿Buscar archivos cuyos nombres de ruta contengan varias palabras sin un orden específico entre ellas?

  5. ¿Buscar archivos en un directorio y enviar el resultado a un archivo de texto?

Newsboat:un lector de fuentes RSS/Atom de línea de comandos para consolas de texto

Cómo agregar números de línea a archivos de texto en Linux

Cómo buscar archivos desde la línea de comandos de Linux

Cómo encontrar archivos que contengan una cadena de texto específica en Linux

linux:busque archivos de tipo *.php recientemente modificados

Cómo buscar un archivo en archivos war, ear y jar recursivamente en Linux