Como parte de este script, necesito poder verificar si el primer argumento dado coincide con la primera palabra del archivo. Si lo hace, salga con un mensaje de error; si no es así, agregue los argumentos al archivo. Entiendo cómo escribir la if
declaración, pero no cómo usarla grep
dentro de un script. Entiendo que grep
se verá algo así
grep ^$1 schemas.txt
Siento que esto debería ser mucho más fácil de lo que lo estoy haciendo.
Recibo un error "demasiados argumentos" en la if
declaración. Me deshice del espacio entre grep -q
y luego obtuve un error binario de operador esperado.
if [ grep -q ^$1 schemas.txt ]
then
echo "Schema already exists. Please try again"
exit 1
else
echo "$@" >> schemas.txt
fi
[
...]
y funcionará. Aunque probablemente desee citar su patrón:if grep -q "^$1" schemas.txt; then …
Respuestas:
grep
devuelve un código de salida diferente si encuentra algo (cero) frente a si no ha encontrado nada (distinto de cero). En unaif
declaración, un código de salida cero se asigna a "verdadero" y un código de salida distinto de cero se asigna a falso. Además, grep tiene un-q
argumento para no generar el texto coincidente (sino que solo devuelve el código de estado de salida)Entonces, puedes usar grep así:
Como nota rápida, cuando haces algo así
if [ -z "$var" ]…
, resulta que en[
realidad es un comando que estás ejecutando, al igual que grep. En mi sistema, es/usr/bin/[
. (Bueno, técnicamente, su shell probablemente lo tiene incorporado, pero eso es una optimización. Se comporta como si fuera un comando). Funciona de la misma manera,[
devuelve un código de salida cero para verdadero, un código de salida distinto de cero para falso. (test
es lo mismo que[
, excepto por el cierre]
)fuente
ls -l /usr/bin/\[
yman [
para ver que[
es un programa como cualquier otro, solo parece un elemento sintáctico, esto debería hacerlo obvio y más fácil de entender. (por conveniencia,[
también está integrado en bash, dash y otros, pero sigue siendo un comando). También pruebatype -all [
en bash.-q
opción, esa opción le dice a grep que esté en silencio (no imprima las líneas coincidentes).Otra forma simple es usar
grep -c
.Eso genera (no devuelve como código de salida), el número de líneas que coinciden con el patrón, por lo que 0 si no hay coincidencia o 1 o más si existe una coincidencia.
Entonces, si desea verificar que el patrón coincida 3 o más veces, debería hacer lo siguiente:
fuente
grep -cim1
en su lugar.Sé que llego tarde a esto, pero me encanta esta versión corta:
fuente
Si queremos capturar la primera palabra de un archivo, necesitamos agregar
-zw
a grepSin
-z
nosotros tenemos la primera palabra de una línea. Sin-w
nosotros obtenemos palabras parciales.fuente
Si desea usarlo entre corchetes, puede ejecutar lo siguiente
Esta lógica funciona para todos los comandos, solo coloque sus comandos dentro del botón de retroceso (el botón arriba de la pestaña o hacia abajo del botón Esc o hacia la izquierda de 1 botón)
fuente
`grep -q PATTERN file.txt`
, de lo contrario, se aplica el operador split + glob y eso causaría problemas para cualquier salida que contenga caracteres$IFS
comodín o caracteres. En términos más generales,[ "`cmd`" ]
devolvería verdadero sicmd
genera al menos una línea no vacía en stdout (con problemas potenciales si genera bytes NUL). Eso significa que el shell tendrá que almacenar toda la salida en la memoria y esperar a que termine. Usar en suif cmd | grep -q .
lugar puede ser preferible en ese sentido.-q
interruptor es suprimirgrep
la salida. Está diciendo: Verifique PATTERN en file.txt, suprima cualquier salida, luego configure el estado de retorno de acuerdo con si se encontró PATTERN. Luego, ignore el estado de retorno, tome la salida del comando (que forzamos a estar vacía), aplique la división de palabras y la expansión global de archivos (sin ningún argumento), luego ejecute el comando[
(akatest
) con exactamente un argumento, a saber ,]
--y luego, dado que eso dará como resultado un error, echo "no encontrado". @ StéphaneChazelas, ¿me perdí algo?-q
. Ese comentario habría tenido sentido[ `grep PATTERN file.txt ` ]
, pero como se insinuó en el comentario,[ "`grep -n PATTERN file.txt`" ]
sería mejor si PATTERN pudiera coincidir solo con líneas vacías. Aunque aquí, por supuesto, es loif grep -q PATTERN file.txt
que quieres.