Interprete PATTERN como una lista de cadenas fijas, separadas por líneas nuevas, cualquiera de las cuales debe coincidir.
-x, --line-regexp
Seleccione solo aquellas coincidencias que coincidan exactamente con la línea completa.
-q` --quiet`--silent
Tranquilo; No escriba nada en la salida estándar. Salga inmediatamente con estado cero si se encuentra alguna coincidencia, incluso si se detectó un error. Consulte también la opción -su --no-messages.
Manejo de errores
Como se señala correctamente en los comentarios, el enfoque anterior trata silenciosamente los casos de error como si se encontrara la cadena. Si desea manejar los errores de una manera diferente, tendrá que omitir la -qopción y detectar errores en función del estado de salida:
Normalmente, el estado de salida es 0 si se encuentran líneas seleccionadas y 1 en caso contrario. Pero el estado de salida es 2 si se produjo un error, a menos que el-q o --quieto --silentde opciones se utiliza y se encuentra una línea seleccionada. Tenga en cuenta, sin embargo, que sólo POSIX mandatos, para los programas tales como grep, cmpy diff, que el estado de salida en caso de error sea mayor que 1; Por lo tanto, es aconsejable, en aras de la portabilidad, utilizar una lógica que pruebe esta condición general en lugar de una estricta igualdad con 2.
Para suprimir la salida normal de grep, puede redirigirla a /dev/null. Tenga en cuenta que el error estándar no se dirige, por lo que cualquier mensaje de error que grepse imprima terminará en la consola como probablemente desee.
Para manejar los tres casos, podemos usar una casedeclaración:
case`grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?`in0)# code if found;;1)# code if not found;;*)# code if an error occurred;;esac
Si ejecuto este comando desde bash script, ¿cómo atrapar 0 o 1 en una variable?
Toren
66
@Toren Se puede acceder al estado de salida más reciente mediante $?. También puede usar el comando grep junto con la ifinstrucción (como se muestra en la respuesta actualizada).
Shawn Chin
55
Puede usar grep -Fqx "$FILENAME"y no tiene que preocuparse por los caracteres regex en los contenidos variables y no tendrá que usarlos en la cadena de búsqueda.
Pausado hasta nuevo aviso.
44
Un par de notas para las personas que miran esta respuesta: 1) En bash, 0 siempre es verdadero y cualquier otra cosa siempre es falsa 2) Solo use la bandera -x si desea que toda la línea coincida exactamente. Si solo desea saber si su cadena existe en el archivo, déjelo desactivado. Si desea saber si su cadena existe exactamente pero sin coincidir necesariamente con una línea completa (es decir, como una palabra completa), use -w.
Schmick
1
No entiendo, -q / --silent¿se necesita? Falsamente dice "todo bien" golpear incluso si ocurre un error. Si entendí eso correctamente. Parece un concepto defectuoso para este caso.
redanimalwar
90
En cuanto a la siguiente solución:
grep -Fxq"$FILENAME" my_list.txt
En caso de que se pregunte (como lo hice) qué -Fxqsignifica en inglés simple:
F: Afecta cómo se interpreta PATTERN (cadena fija en lugar de una expresión regular)
x: Unir toda la línea
q: Shhhhh ... impresión mínima
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.)
-F no afecta el procesamiento del archivo, afecta cómo se interpreta PATTERN. Típicamente, PATTERN se interpreta como una expresión regular, pero con -F se interpretará como una cadena fija.
Adam S
41
Tres métodos en mi mente:
1) Prueba corta para un nombre en una ruta (no estoy seguro de que este sea tu caso)
ls -a "path"| grep "name"
2) Prueba corta para una cadena en un archivo
grep -R "string""filepath"
3) Script de bash más largo usando regex
#!/bin/bash
declare file="content.txt"
declare regex="\s+string\s+"
declare file_content=$( cat "${file}")if[[" $file_content "=~ $regex ]]# please note the space before and after the file contentthen
echo "found"else
echo "not found"fi
exit
Esto debería ser más rápido si tiene que probar varias cadenas en el contenido de un archivo usando un bucle, por ejemplo, cambiando la expresión regular en cualquier ciclo.
No necesita probar la salida de grep, solo puede usar grep -qy llamar a grep directamente ifcomo lo hace Thomas en su respuesta. Además, la pregunta no incluía verificar si el directorio existe antes de agregarlo a la lista (después de todo, podría ser una lista de directorios eliminados).
sorigal
Eliminé el script de ejemplo, no agregó nada a la respuesta dada por Thomas.
lecodesportif
3
Si solo desea verificar la existencia de una línea, no necesita crear un archivo. P.ej,
if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ;then# code for if it existselse# code for if it does not existfi
La solución de @ Thomas no funcionó para mí por alguna razón, pero tenía una cadena más larga con caracteres especiales y espacios en blanco, así que simplemente cambié los parámetros de esta manera:
if grep -Fxq'string you want to find'"/path/to/file";then
echo "Found"else
echo "Not found"fi
Respuestas:
El estado de salida es 0 (verdadero) si se encontró el nombre, 1 (falso) si no, entonces:
Explicación
Aquí están las secciones relevantes de la página del manual para
grep
:Manejo de errores
Como se señala correctamente en los comentarios, el enfoque anterior trata silenciosamente los casos de error como si se encontrara la cadena. Si desea manejar los errores de una manera diferente, tendrá que omitir la
-q
opción y detectar errores en función del estado de salida:Para suprimir la salida normal de
grep
, puede redirigirla a/dev/null
. Tenga en cuenta que el error estándar no se dirige, por lo que cualquier mensaje de error quegrep
se imprima terminará en la consola como probablemente desee.Para manejar los tres casos, podemos usar una
case
declaración:fuente
$?
. También puede usar el comando grep junto con laif
instrucción (como se muestra en la respuesta actualizada).grep -Fqx "$FILENAME"
y no tiene que preocuparse por los caracteres regex en los contenidos variables y no tendrá que usarlos en la cadena de búsqueda.-q / --silent
¿se necesita? Falsamente dice "todo bien" golpear incluso si ocurre un error. Si entendí eso correctamente. Parece un concepto defectuoso para este caso.En cuanto a la siguiente solución:
En caso de que se pregunte (como lo hice) qué
-Fxq
significa en inglés simple:F
: Afecta cómo se interpreta PATTERN (cadena fija en lugar de una expresión regular)x
: Unir toda la líneaq
: Shhhhh ... impresión mínimaDel archivo man:
fuente
Tres métodos en mi mente:
1) Prueba corta para un nombre en una ruta (no estoy seguro de que este sea tu caso)
2) Prueba corta para una cadena en un archivo
3) Script de bash más largo usando regex
Esto debería ser más rápido si tiene que probar varias cadenas en el contenido de un archivo usando un bucle, por ejemplo, cambiando la expresión regular en cualquier ciclo.
fuente
Manera más simple:
Consejo: envíe a
/dev/null
si desea el estado de salida del comando, pero no las salidas.fuente
-q
el mismo que--quiet
:)-q
mejor respuesta aquí, y es el cuarto lugar. No hay justicia en este mundo.La forma más fácil y sencilla sería:
grep -c devolverá el recuento de cuántas veces se produce la cadena en el archivo.
fuente
Si entendí tu pregunta correctamente, esto debería hacer lo que necesitas.
En una linea :
check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
fuente
grep -q
y llamar a grep directamenteif
como lo hace Thomas en su respuesta. Además, la pregunta no incluía verificar si el directorio existe antes de agregarlo a la lista (después de todo, podría ser una lista de directorios eliminados).Si solo desea verificar la existencia de una línea, no necesita crear un archivo. P.ej,
fuente
Mi versión usando fgrep
fuente
-c
opción enfgrep --help
La opción -E hace que grep use expresiones regulares
fuente
La solución de @ Thomas no funcionó para mí por alguna razón, pero tenía una cadena más larga con caracteres especiales y espacios en blanco, así que simplemente cambié los parámetros de esta manera:
Espero que ayude a alguien
fuente
Una solución sin grep, funciona para mí:
basado en: https://stackoverflow.com/a/229606/3306354
fuente
grep -q
descrito en la respuesta aceptada es el enfoque más eficiente.fuente
fuente