Cómo verificar si un archivo contiene una cadena específica usando Bash

Respuestas:

466
if grep -q SomeString "$File"; then
  Some Actions # SomeString was found
fi

No necesitas [[ ]]aquí. Simplemente ejecute el comando directamente. Agregue la -qopción cuando no necesite la cadena que se muestra cuando se encontró.

El grepcomando devuelve 0 o 1 en el código de salida según el resultado de la búsqueda. 0 si se encontró algo; 1 de lo contrario.

$ echo hello | grep hi ; echo $?
1
$ echo hello | grep he ; echo $?
hello
0
$ echo hello | grep -q he ; echo $?
0

Puede especificar comandos como condición de if. Si el comando devuelve 0 en su código de salida, eso significa que la condición es verdadera; de lo contrario falso.

$ if /bin/true; then echo that is true; fi
that is true
$ if /bin/false; then echo that is true; fi
$

Como puede ver, ejecuta aquí los programas directamente. No adicional []o [[]].

Igor Chubin
fuente
Más información grepy opciones disponibles en asnwer stackoverflow.com/a/4749368/1702557
Pawel
2
es posible que desee considerar los -Fxqparámetros como en stackoverflow.com/a/4749368/544721
Grzegorz Wierzowiecki
3
considere usar -m 1para mejorar el rendimiento del escaneo. Retornos en la primera aparición.
AlikElzin-kilaka
1
si SomeStringcontiene caracteres especiales regex (como .), puede obtener resultados inesperados. Es más seguro usar siempre fgrep(o grep -F) (a menos que realmente necesite una expresión regular, en cuyo caso egrep(o grep -E) es probablemente la mejor opción)
Walter Tross
El ejemplo de ifejemplo es incorrecto, ya que solo comprueba si el código de salida no es 0. Si ocurre algún error, como si el archivo no se puede leer, el código de salida también es distinto de 0. Por lo tanto, debe hacer algo como ec=$?, y verificar si está 0(encontrado), luego si está 1(no encontrado) y luego si es otra cosa (falla).
ddekany
40

Además de otras respuestas, que le indicaron cómo hacer lo que quería, trato de explicar lo que estaba mal (que es lo que quería).

En Bash, ifdebe seguirse con un comando. Si el código de salida de este comando es igual a 0, entonces la thenparte se ejecuta, de lo contrario, se ejecuta la elseparte.

Puede hacerlo con cualquier comando como se explica en otras respuestas: if /bin/true; then ...; fi

[[es un comando bash interno dedicado a algunas pruebas, como la existencia de archivos, comparaciones variables. Del mismo modo, se [trata de un comando externo (se encuentra típicamente en /usr/bin/[) que realiza aproximadamente las mismas pruebas pero necesita ]como argumento final, por lo que ]debe rellenarse con un espacio a la izquierda, que no es el caso ]].

Aquí no necesitas [[ni [.

Otra cosa es la forma de citar las cosas. En bash, solo hay un caso en el que anidan pares de comillas, es "$(command "argument")". Pero en 'grep 'SomeString' $File'usted solo tiene una palabra, porque 'grep 'es una unidad entre comillas, que se concatena SomeStringy luego se concatena nuevamente con ' $File'. La variable $Fileni siquiera se reemplaza por su valor debido al uso de comillas simples. La forma correcta de hacerlo es grep 'SomeString' "$File".

Benoit
fuente
15

En caso de que desee verificar si el archivo no contiene una cadena específica, puede hacerlo de la siguiente manera.

if ! grep -q SomeString "$File"; then
  Some Actions # SomeString was not found
fi
Lahiru Chandima
fuente
10
##To check for a particular  string in a file

cd PATH_TO_YOUR_DIRECTORY #Changing directory to your working directory
File=YOUR_FILENAME  
if grep -q STRING_YOU_ARE_CHECKING_FOR "$File"; ##note the space after the string you are searching for
then
echo "Hooray!!It's available"
else
echo "Oops!!Not available"
fi
Nevin Raj Victor
fuente
2
Cambiar el directorio generalmente no es una buena idea (y es completamente innecesario aquí, solo califique el nombre del archivo con el directorio de destino). Y luego, lo que tiene es exactamente lo mismo que la respuesta aceptada, solo que con menos detalles.
Mat
Gracias por el consejo Mat
Nevin Raj Victor
7

Versión más corta (correcta):

grep -q "something" file; [ $? -eq 0 ] && echo "yes" || echo "no"

también se puede escribir como

grep -q "something" file; test $? -eq 0 && echo "yes" || echo "no"

pero no necesita probarlo explícitamente en este caso, así que lo mismo con:

grep -q "something" file && echo "yes" || echo "no"
lzap
fuente
3
if grep -q something file; then echo yes; else echo no; fi. No hay razón para meterse $?en absoluto.
Charles Duffy
6

En caso de que desee verificar si la cadena coincide con la línea completa y si es una cadena fija, puede hacerlo de esta manera

grep -Fxq [String] [filePath]

ejemplo

 searchString="Hello World"
 file="./test.log"
 if grep -Fxq "$searchString" $file
    then
            echo "String found in $file"
    else
            echo "String not found in $file"
 fi

Del archivo man:

-F, --fixed-strings

          Interpret  PATTERN  as  a  list of fixed strings, separated by newlines, any of 

which is to be matched.
          (-F is specified by POSIX.)
-x, --line-regexp
          Select only those matches that exactly match the whole line.  (-x is specified by 

POSIX.)
-q, --quiet, --silent
          Quiet; do not write anything to standard output.  Exit immediately with zero 

status  if  any  match  is
          found,  even  if  an error was detected.  Also see the -s or --no-messages 

option.  (-q is specified by
          POSIX.)
Shubham Khatri
fuente
6
grep -q [PATTERN] [FILE] && echo $?

El estado de salida es 0(verdadero) si se encontró el patrón; de lo contrario, cadena en blanco.

SupermanKelly
fuente
4
if grep -q [string] [filename]
then
    [whatever action]
fi

Ejemplo

if grep -q 'my cat is in a tree' /tmp/cat.txt
then
    mkdir cat
fi
usuario5854766
fuente
2

Prueba esto:

if [[ $(grep "SomeString" $File) ]] ; then
   echo "Found"
else
   echo "Not Found"
fi
vgokul129
fuente
3
Estoy vacilante absteniéndome de votar en contra de esto, pero Stack Overflow no debería perpetuar este tipo de lógica de pretzel. grepdevuelve un estado de salida por una muy buena razón; capturar la salida en una cadena potencialmente almacenará una gran cantidad de texto en un búfer solo para que pueda decir que no está vacío.
tripleee
-1

Hice esto, parece funcionar bien

if grep $SearchTerm $FileToSearch; then
   echo "$SearchTerm found OK"
else
   echo "$SearchTerm not found"
fi
madarekrap
fuente
La cita está rota y probablemente desee evitar ver la salida de grep.
tripleee
-3
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"
chemila
fuente
1
Tienes un error tipográfico? se supone que es $?
lzap
... no solo está destinado a serlo $?, sino que no hay necesidad de eso, simplemente podrías hacerloif grep -q ...
Charles Duffy
1
Además, foo && truthy_action || falsey_actionno es un operador ternario real: si truthy_actionfalla, falsey_actionse ejecuta además .
Charles Duffy
De manera más general, el propósito de ifes ejecutar un comando y verificar su código de salida. Muy raramente debería examinarse $?explícitamente.
tripleee