Tengo un archivo que contiene nombres de directorio:
my_list.txt
:
/tmp
/var/tmp
Me gustaría registrar Bash antes de agregar un nombre de directorio si ese nombre ya existe en el archivo.
Tengo un archivo que contiene nombres de directorio:
my_list.txt
:
/tmp
/var/tmp
Me gustaría registrar Bash antes de agregar un nombre de directorio si ese nombre ya existe en el archivo.
Respuestas:
grep -Fxq "$FILENAME" my_list.txt
El estado de salida es 0 (verdadero) si se encontró el nombre, 1 (falso) si no, entonces:
if grep -Fxq "$FILENAME" my_list.txt
then
# code if found
else
# code if not found
fi
Aquí están las secciones relevantes de la página del manual paragrep
:
grep [options] PATTERN [FILE...]
-F
,--fixed-strings
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
-s
u--no-messages
.
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:
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--quiet
o--silent
de opciones se utiliza y se encuentra una línea seleccionada. Tenga en cuenta, sin embargo, que sólo POSIX mandatos, para los programas tales comogrep
,cmp
ydiff
, 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 grep
se imprima terminará en la consola como probablemente desee.
Para manejar los tres casos, podemos usar una case
declaración:
case `grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?` in
0)
# code if found
;;
1)
# code if not found
;;
*)
# code if an error occurred
;;
esac
$?
. También puede usar el comando grep junto con la if
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:
grep -Fxq "$FILENAME" my_list.txt
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:
-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.)
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 content
then
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.
Manera más simple:
if grep "$filename" my_list.txt > /dev/null
then
... found
else
... not found
fi
Consejo: envíe a /dev/null
si desea el estado de salida del comando, pero no las salidas.
-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:
isInFile=$(cat file.txt | grep -c "string")
if [ $isInFile -eq 0 ]; then
#string not contained in file
else
#string is in file at least once
fi
grep -c devolverá el recuento de cuántas veces se produce la cadena en el archivo.
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
grep -q
y llamar a grep directamente if
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).
grep -E "(string)" /path/to/file || echo "no match found"
La opción -E hace que grep use expresiones regulares
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
Espero que ayude a alguien
Una solución sin grep, funciona para mí:
MY_LIST=$( cat /path/to/my_list.txt )
if [[ "${MY_LIST}" == *"${NEW_DIRECTORY_NAME}"* ]]; then
echo "It's there!"
else
echo "its not there"
fi
basado en: https://stackoverflow.com/a/229606/3306354
grep -q
descrito en la respuesta aceptada es el enfoque más eficiente.
grep -Fxq "String to be found" | ls -a