Como parte desse script, preciso verificar se o primeiro argumento fornecido corresponde à primeira palavra do arquivo. Se houver, saia com uma mensagem de erro; caso contrário, anexe os argumentos ao arquivo. Eu entendo como escrever a if
declaração, mas não como usar grep
em um script. Eu entendo que grep
será algo parecido com isto
grep ^$1 schemas.txt
Eu sinto que isso deve ser muito mais fácil do que estou fazendo.
Estou recebendo um erro "muitos argumentos" na if
declaração. Eu me livrei do espaço entre elas grep -q
e recebi um erro que o operador binário esperava.
if [ grep -q ^$1 schemas.txt ]
then
echo "Schema already exists. Please try again"
exit 1
else
echo "$@" >> schemas.txt
fi
[
...]
e vai funcionar. Embora você provavelmente queira citar seu padrão:if grep -q "^$1" schemas.txt; then …
Respostas:
grep
retorna um código de saída diferente se encontrou algo (zero) vs. se não encontrou nada (diferente de zero). Em umaif
instrução, um código de saída zero é mapeado para "true" e um código de saída diferente de zero é mapeado para false. Além disso, o grep tem um-q
argumento para não gerar o texto correspondente (mas retornar apenas o código de status de saída)Então, você pode usar o grep assim:
Como uma observação rápida, quando você faz algo como
if [ -z "$var" ]…
, acontece que[
na verdade é um comando que você está executando, assim como o grep. No meu sistema, é/usr/bin/[
. (Bem, tecnicamente, seu shell provavelmente o possui, mas isso é uma otimização. Ele se comporta como se fosse um comando). Funciona da mesma maneira,[
retorna um código de saída zero para true, e um código de saída diferente de zero para false. (test
é a mesma coisa que[
, exceto no fechamento]
)fonte
ls -l /usr/bin/\[
e,man [
para ver que[
é um programa como outro qualquer, apenas parece um elemento sintático - isso deve tornar óbvio e fácil de entender. (por conveniência,[
também é incorporado no bash, dash e outros - mas ainda é um comando). também tentetype -all [
no bash.-q
opção que diz ao grep para ficar quieto (não imprima as linhas correspondentes).Outra maneira simples é usar
grep -c
.Isso gera (não retorna como código de saída), o número de linhas que correspondem ao padrão; portanto, 0 se não houver correspondência ou 1 ou mais se houver correspondência.
Portanto, se você quiser verificar se o padrão é correspondido 3 ou mais vezes, faça:
fonte
grep -cim1
vez disso.Eu sei que estou atrasado para isso, mas eu amo esta versão curta:
fonte
Se queremos pegar a primeira palavra de um arquivo, precisamos adicionar
-zw
ao grepSem
-z
obter a primeira palavra de uma linha. Sem-w
termos palavras parciais.fonte
Se você quiser usá-lo com colchetes, você pode executar o procedimento abaixo
Essa lógica funciona para todos os comandos. Basta colocar seus comandos dentro do backtick (o botão acima da guia ou na parte inferior do botão Esc ou à esquerda do botão 1)
fonte
`grep -q PATTERN file.txt`
, caso contrário, o operador split + glob será aplicado e isso causaria problemas para qualquer saída que contenha caracteres$IFS
ou caracteres curinga. De maneira mais geral,[ "`cmd`" ]
retornaria true secmd
gerar pelo menos uma linha não vazia no stdout (com problemas em potencial se gerar NUL bytes). Isso significa que o shell precisará armazenar toda a saída na memória e aguardar o término. O usoif cmd | grep -q .
pode ser preferível nesse sentido.-q
switch é suprimirgrep
a saída. Você está dizendo: Verifique PATTERN no arquivo.txt, suprima qualquer saída e defina o status de retorno de acordo com a localização do PATTERN. Em seguida, ignore o status de retorno, pegue a saída do comando (que forçamos a ficar vazia), aplique a divisão de palavras e a expansão do arquivo global (resultando em nenhum argumento) e execute o comando[
(akatest
) com exatamente um argumento - a saber ,]
--e então, como isso resultará em um erro, ecoe "não encontrado". @ StéphaneChazelas, eu perdi alguma coisa?-q
. Esse comentário teria feito sentido[ `grep PATTERN file.txt ` ]
, mas, como sugerido no comentário,[ "`grep -n PATTERN file.txt`" ]
seria melhor se PATTERN corresponder apenas a linhas vazias. Embora aqui, é claro,if grep -q PATTERN file.txt
você queira.