Interprete PATTERN como uma lista de cadeias fixas, separadas por novas linhas, qualquer uma das quais deve ser correspondida.
-x, --line-regexp
Selecione apenas as correspondências que correspondam exatamente à linha inteira.
-q, --quiet,--silent
Quieto; não escreva nada na saída padrão. Saia imediatamente com o status zero se alguma correspondência for encontrada, mesmo que um erro tenha sido detectado. Veja também a opção -sou --no-messages.
Manipulação de erros
Como corretamente apontado nos comentários, a abordagem acima trata silenciosamente os casos de erro como se a sequência fosse encontrada. Se você deseja lidar com erros de uma maneira diferente, precisará omitir a -qopção e detectar erros com base no status de saída:
Normalmente, o status de saída é 0 se as linhas selecionadas forem encontradas e 1 caso contrário. Mas o status de saída é 2 se ocorrer um erro, a menos que a opção -qou --quietou --silentseja usada e uma linha selecionada seja encontrada. Note, no entanto, que POSIX apenas mandatos, para programas como grep, cmpe diffque o status de saída em caso de erro ser maior do que 1; portanto, é recomendável, por uma questão de portabilidade, usar a lógica que testa essa condição geral em vez da estrita igualdade com 2.
Para suprimir a saída normal de grep, você pode redirecioná-la para /dev/null. Observe que o erro padrão permanece sem direcionamento; portanto, qualquer mensagem de erro que greppossa ser impressa será finalizada no console como você provavelmente desejaria.
Para lidar com os três casos, podemos usar uma casedeclaração:
case`grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?`in0)# code if found;;1)# code if not found;;*)# code if an error occurred;;esac
Se eu executar este comando a partir do script bash, como capturar 0 ou 1 em uma variável?
Toren
6
@Toren O status de saída mais recente pode ser acessado usando $?. você também pode usar o comando grep ao lado da ifinstrução (como mostrado na resposta atualizada).
Shawn Chin
5
Você pode usar grep -Fqx "$FILENAME"e não precisa se preocupar com caracteres regex no conteúdo da variável e não precisará usá-los na string de pesquisa.
Pausado até novo aviso.
4
Algumas notas para as pessoas que olham para esta resposta: 1) No bash, 0 é sempre verdadeiro e tudo o mais é sempre falso 2) Use apenas o sinalizador -x se desejar que toda a linha corresponda exatamente. Se você apenas deseja descobrir se sua string existe no arquivo, deixe-a assim. Se você quiser descobrir se sua string existe exatamente, mas sem corresponder necessariamente a uma linha inteira (por exemplo, como uma palavra inteira), use -w.
217 Schmick
11
Eu não entendo o que -q / --silenté necessário? Diz falsamente "tudo de bom" para bater, mesmo que ocorra um erro. Se eu entendi direito. Parece um conceito defeituoso para este caso.
Redanimalwar # 7/19
90
Em relação à seguinte solução:
grep -Fxq"$FILENAME" my_list.txt
Caso você esteja se perguntando (como eu) o que -Fxqsignifica em inglês simples:
F: Afeta como PATTERN é interpretado (sequência fixa em vez de uma expressão regular)
x: Corresponder a linha inteira
q: Shhhhh ... impressão mínima
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.)
-F não afeta o processamento do arquivo, afeta como o PATTERN é interpretado. Normalmente, PATTERN é interpretado como uma expressão regular, mas com -F será interpretado como uma sequência fixa.
12133 Adam S
41
Três métodos em minha mente:
1) Teste curto para um nome em um caminho (não tenho certeza se esse pode ser o seu caso)
ls -a "path"| grep "name"
2) Teste curto para uma string em um arquivo
grep -R "string""filepath"
3) Script bash mais longo 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
Isso deve ser mais rápido se você precisar testar várias strings em um conteúdo de arquivo usando um loop, por exemplo, alterando a regex em qualquer ciclo.
Você não precisa testar a saída do grep, basta usar grep -qe chamar o grep diretamente, ifcomo Thomas faz em sua resposta. Além disso, a pergunta não incluiu a verificação da existência do diretório antes de adicioná-lo à lista (afinal, poderia ser uma lista de diretórios excluídos).
sorpigal
Eu removi o script de exemplo, ele não adicionou nada à resposta dada por Thomas.
Lecodesportif
3
Se você apenas deseja verificar a existência de uma linha, não precisa criar um arquivo. Por exemplo,
if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ;then# code for if it existselse# code for if it does not existfi
A solução do @ Thomas não funcionou para mim por algum motivo, mas eu tinha uma string mais longa com caracteres especiais e espaços em branco, então apenas alterei os parâmetros assim:
if grep -Fxq'string you want to find'"/path/to/file";then
echo "Found"else
echo "Not found"fi
Respostas:
O status de saída é 0 (verdadeiro) se o nome foi encontrado, 1 (falso) se não, então:
Explicação
Aqui estão as seções relevantes da página de manual para
grep
:Manipulação de erros
Como corretamente apontado nos comentários, a abordagem acima trata silenciosamente os casos de erro como se a sequência fosse encontrada. Se você deseja lidar com erros de uma maneira diferente, precisará omitir a
-q
opção e detectar erros com base no status de saída:Para suprimir a saída normal de
grep
, você pode redirecioná-la para/dev/null
. Observe que o erro padrão permanece sem direcionamento; portanto, qualquer mensagem de erro quegrep
possa ser impressa será finalizada no console como você provavelmente desejaria.Para lidar com os três casos, podemos usar uma
case
declaração:fonte
$?
. você também pode usar o comando grep ao lado daif
instrução (como mostrado na resposta atualizada).grep -Fqx "$FILENAME"
e não precisa se preocupar com caracteres regex no conteúdo da variável e não precisará usá-los na string de pesquisa.-q / --silent
é necessário? Diz falsamente "tudo de bom" para bater, mesmo que ocorra um erro. Se eu entendi direito. Parece um conceito defeituoso para este caso.Em relação à seguinte solução:
Caso você esteja se perguntando (como eu) o que
-Fxq
significa em inglês simples:F
: Afeta como PATTERN é interpretado (sequência fixa em vez de uma expressão regular)x
: Corresponder a linha inteiraq
: Shhhhh ... impressão mínimaNo arquivo man:
fonte
Três métodos em minha mente:
1) Teste curto para um nome em um caminho (não tenho certeza se esse pode ser o seu caso)
2) Teste curto para uma string em um arquivo
3) Script bash mais longo usando regex:
Isso deve ser mais rápido se você precisar testar várias strings em um conteúdo de arquivo usando um loop, por exemplo, alterando a regex em qualquer ciclo.
fonte
Maneira mais simples:
Dica: envie para
/dev/null
se desejar o status de saída do comando, mas não as saídas.fonte
-q
que é o mesmo que--quiet
:)-q
melhor resposta também aqui e é o quarto lugar. não há justiça neste mundo.A maneira mais fácil e simples seria:
grep -c retornará a contagem de quantas vezes a string ocorre no arquivo.
fonte
Se entendi sua pergunta corretamente, isso deve fazer o que você precisa.
Em uma linha :
check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
fonte
grep -q
e chamar o grep diretamente,if
como Thomas faz em sua resposta. Além disso, a pergunta não incluiu a verificação da existência do diretório antes de adicioná-lo à lista (afinal, poderia ser uma lista de diretórios excluídos).Se você apenas deseja verificar a existência de uma linha, não precisa criar um arquivo. Por exemplo,
fonte
Minha versão usando fgrep
fonte
-c
opção emfgrep --help
A opção -E faz com que o grep use expressões regulares
fonte
A solução do @ Thomas não funcionou para mim por algum motivo, mas eu tinha uma string mais longa com caracteres especiais e espaços em branco, então apenas alterei os parâmetros assim:
Espero que ajude alguém
fonte
Uma solução grep-less funciona para mim:
baseado em: https://stackoverflow.com/a/229606/3306354
fonte
grep -q
descrito na resposta aceita é a abordagem mais eficiente.fonte
ls
aceita entrada padrão?fonte