Como verificar se um arquivo contém uma sequência específica usando o Bash

Respostas:

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

Você não precisa [[ ]]aqui. Basta executar o comando diretamente. Adicione a -qopção quando você não precisar da string exibida quando foi encontrada.

O grepcomando retorna 0 ou 1 no código de saída, dependendo do resultado da pesquisa. 0 se algo foi encontrado; 1 caso contrário.

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

Você pode especificar comandos como uma condição de if. Se o comando retornar 0 em seu código de saída, isso significa que a condição é verdadeira; caso contrário, falso.

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

Como você pode ver, execute aqui os programas diretamente. Nenhum adicional []ou [[]].

Igor Chubin
fonte
Mais informações sobre grepe opções disponíveis em asnwer stackoverflow.com/a/4749368/1702557
Pawel
2
pode querer considerar -Fxqparâmetros como em stackoverflow.com/a/4749368/544721
Grzegorz Wierzowiecki
3
considere usar -m 1para melhorar o desempenho da digitalização. Retorna na primeira ocorrência.
AlikElzin-Kilaka
1
se SomeStringcontiver caracteres especiais de regex (como .), você poderá obter resultados inesperados. É mais seguro usar sempre fgrep(ou grep -F) (a menos que você realmente precisa de um regex, caso em que egrep(ou grep -E) é provavelmente a melhor escolha)
Walter Tross
O exemplo de ifexemplo está incorreto, pois apenas verifica se o código de saída era diferente de 0. Se ocorrer algum erro, como o arquivo não pode ser lido, o código de saída também será diferente de 0. Então você tem que fazer algo como ec=$?e verificar se é 0(encontrado), se é 1(não encontrado) e se é outra coisa (falha).
ddekany
40

Além de outras respostas, que lhe ensinaram como fazer o que você queria, tento explicar o que estava errado (o que você queria.

No Bash, ifdeve ser seguido com um comando. Se o código de saída deste comando for igual a 0, a thenparte será executada; caso contrário, a elseparte, se houver, será executada.

Você pode fazer isso com qualquer comando, conforme explicado em outras respostas: if /bin/true; then ...; fi

[[é um comando bash interno dedicado a alguns testes, como existência de arquivo, comparações de variáveis. Da mesma forma, [é um comando externo (normalmente localizado em /usr/bin/[) que executa aproximadamente os mesmos testes, mas precisa ]como argumento final, e é por isso que ]deve ser preenchido com um espaço à esquerda, o que não é o caso ]].

Aqui você não precisa [[nem [.

Outra coisa é a maneira como você cita as coisas. No bash, há apenas um caso em que pares de aspas se aninham, é isso "$(command "argument")". Mas 'grep 'SomeString' $File'você tem apenas uma palavra, porque 'grep 'é uma unidade citada, que é concatenada com SomeStringe depois concatenada com ' $File'. A variável $Filenem é substituída por seu valor por causa do uso de aspas simples. A maneira correta de fazer isso é grep 'SomeString' "$File".

Benoit
fonte
15

Caso deseje verificar se o arquivo não contém uma sequência específica, você pode fazer o seguinte.

if ! grep -q SomeString "$File"; then
  Some Actions # SomeString was not found
fi
Lahiru Chandima
fonte
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
fonte
2
Alterar o diretório geralmente não é uma boa ideia (e é completamente desnecessário aqui, apenas qualifique o nome do arquivo com o diretório de destino). E então o que você tem é exatamente a mesma coisa que a resposta aceita, apenas com menos detalhes.
Tapete de
Obrigado pelo conselho Mat
Nevin Raj Victor
7

Versão mais curta (correta):

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

também pode ser escrito como

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

mas você não precisa testá-lo explicitamente nesse caso, o mesmo com:

grep -q "something" file && echo "yes" || echo "no"
lzap
fonte
3
if grep -q something file; then echo yes; else echo no; fi. Não há razão para mexer $?.
Charles Duffy
6

Caso deseje verificar se a string corresponde a toda a linha e se é uma string fixa, você pode fazê-lo desta maneira

grep -Fxq [String] [filePath]

exemplo

 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

No arquivo 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
fonte
6
grep -q [PATTERN] [FILE] && echo $?

O status de saída é 0(verdadeiro) se o padrão foi encontrado; caso contrário, em branco.

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

Exemplo

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

Tente o seguinte:

if [[ $(grep "SomeString" $File) ]] ; then
   echo "Found"
else
   echo "Not Found"
fi
vgokul129
fonte
3
Eu hesito em abster-me de votar isso, mas o Stack Overflow não deve perpetuar esse tipo de lógica de pretzel. grepretorna um status de saída por um motivo muito bom; capturar a saída em uma sequência potencialmente armazenará uma grande quantidade de texto em um buffer, para que você possa dizer que não está vazio.
Tripleee
-1

Eu fiz isso, parece funcionar bem

if grep $SearchTerm $FileToSearch; then
   echo "$SearchTerm found OK"
else
   echo "$SearchTerm not found"
fi
madarekrap
fonte
A citação está quebrada e você provavelmente deseja evitar ver a saída grep.
tripleee
-3
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"
chemila
fonte
1
Você tem um erro de digitação -!? é suposto ser $?
Lzap 23/07/12
... não só é destinado a ser $?, mas não há nenhuma necessidade para que em tudo - você poderia apenas fazerif grep -q ...
Charles Duffy
1
Além disso, foo && truthy_action || falsey_actionnão é um operador ternário real - se truthy_actionfalhar, falsey_actionserá executado além disso .
Charles Duffy
Mais geralmente, a propósito de ifé executar um comando e verificar o seu código de saída. Você raramente precisa examinar $?explicitamente.
Tripleee