Eu tenho um arquivo que tem "então" e "lá".
eu posso
$ grep "then " x.x
x and then some
x and then some
x and then some
x and then some
e eu posso
$ grep "there " x.x
If there is no blob none some will be created
Como posso procurar os dois em uma operação? eu tentei
$ grep (then|there) x.x
-bash: erro de sintaxe próximo ao token inesperado `('
e
grep "(then|there)" x.x
durrantm.../code
# (Nothing)
grep
regular-expression
Michael Durrant
fonte
fonte
Respostas:
Você precisa colocar a expressão entre aspas. O erro que você está recebendo é resultado da interpretação do bash
(
como um caractere especial.Além disso, você precisa dizer ao grep para usar expressões regulares estendidas.
Sem expressões regulares estendidas, você tem que escapar do
|
,(
e)
. Observe que usamos aspas simples aqui. O Bash trata barras invertidas especialmente entre aspas duplas.O agrupamento não é necessário neste caso.
Seria necessário para algo como isto:
fonte
grep $'then\nthere'
egrep -e then -e there
. Observe que isso\|
não é padrão nos BREs. O resto é. Bash trata barras invertidas especialmente dentro de aspas duplas somente antes"
,$
,\
,`
e de nova linha.x.x
?Apenas um adendo rápido, a maioria dos sabores possui um comando chamado egrep, que é apenas grep com -E. Eu pessoalmente gosto muito melhor de digitar
Do que usar grep -E
fonte
O material documentado em EXPRESSÕES REGULARES na (ou pelo menos minha) página de manual é na verdade para regexps estendidos ;
Mas o grep não os usa por padrão - você precisa da
-E
opção:Porque (na página de manual novamente):
Então você também pode usar:
Como os parênteses são supérfluos nesse caso.
fonte
A simplicidade elegante de Bash parece se perder em sua enorme página de manual.
Além das excelentes soluções acima, pensei em tentar dar uma dica sobre como o bash analisa e interpreta as instruções . Em seguida, usando este roteiro, analisarei os exemplos apresentados pelo questionador para ajudá-lo a entender melhor por que eles não funcionam como planejado.
Nota: As linhas de script do shell são usadas diretamente. As linhas de entrada digitadas são primeiro expandidas no histórico.
Cada linha do bash é primeiro tokenizada ou, em outras palavras, dividida no que é chamado de tokens . (A tokenização ocorre antes de todas as outras expansões, incluindo chaves, til, parâmetro, comando, aritmética, processo, divisão de palavras e expansão de nome de arquivo.)
Um token aqui significa uma parte da linha de entrada separada (delimitada) por um desses meta-caracteres especiais:
O Bash usa muitos outros caracteres especiais, mas apenas esses 10 produzem os tokens iniciais.
No entanto, como esses meta-caracteres às vezes também devem ser usados dentro de um token, é preciso haver uma maneira de remover seu significado especial. Isso é chamado de escape. O escape é feito citando uma sequência de um ou mais caracteres (ou seja
'xx..'
,"xx.."
) ou prefixando um caractere individual com uma barra invertida (ou seja\x
). (É um pouco mais complicado que isso porque as aspas também precisam ser citadas e porque aspas duplas não citam tudo, mas essa simplificação será válida por enquanto.)Não confunda citações bash com a idéia de citar uma sequência de texto, como em outros idiomas. O que há entre aspas no bash não são cadeias, mas seções da linha de entrada que possuem metacaracteres escapadas para que não delimitem os tokens.
Observe que há uma diferença importante entre
'
, e"
, mas isso é para outro dia.Os meta-caracteres não escapados restantes se tornam separadores de token.
Por exemplo,
No primeiro exemplo, existem dois tokens produzidos por um delimitador de espaço:
echo
exyz
.Da mesma forma no segundo exemplo.
No terceiro exemplo, o ponto e vírgula é escapado, de forma que há 4 fichas fabricadas por um delimitador de espaço,
echo
,x;
,echo
, ey
. O primeiro token é então executado como o comando e recebe os próximos três tokens como entrada. Observe que o segundoecho
não é executado.A coisa importante a lembrar é que o bash primeiro procura por personagens que escapam (
'
,"
e\
), e em seguida, olha para delimitadores de meta-caracteres unescaped, nessa ordem.Se não escapou, esses 10 caracteres especiais servem como
token
delimitadores. Alguns deles também têm significado adicional, mas, acima de tudo, são delimitadores de token.O que o grep espera
No exemplo acima grep precisa destes sinais,
grep
,string
,filename
.A primeira tentativa da pergunta foi:
Neste caso
(
,)
e|
são caracteres meta unescaped e assim servem para dividir a entrada para estes símbolos:grep
,(
,then
,|
,there
,)
, ex.x
. grep quer vergrep
,then|there
ex.x
.A segunda tentativa da pergunta foi:
Este tokenizes em
grep
,(then|there)
,x.x
. Você pode ver isso se você trocar grep por eco:fonte