Por que o grep está pesquisando mais do que os arquivos que eu quero com asterisco?

1

Dentro de um script bash eu tenho

grep -Ech 'string1|string2' /server/directory/$servername_log_20150312* | awk ...

Eu estava recebendo o erro "too many arguments", por isso liguei set -x e vejo que o grep está tentando procurar iniciar com arquivos como

/server/directory/$servername_log_20150101.000001.log   # Notice the date disparity.

O $servername em cada string está sendo expandido adequadamente com o valor para essa iteração do loop. Por que o grep não está limitado a nomes de arquivos que começam com a string especificada?

    
por WAF 13.03.2015 / 19:11

2 respostas

4

O problema

Vamos começar definindo um nome de servidor:

$ servername=SomeName

Agora tente:

$ echo "$servername_log_20150312"

$

O acima não retorna nada porque (a) o sublinhado é um caractere legal em um nome de variável do shell e (b) nunca definimos servername_log_20150312 .

Agora considere:

/server/directory/$servername_log_20150312*

Após a expansão das variáveis, isso se torna:

/server/directory/*

Após a expansão do nome do caminho, o acima se torna todo arquivo no diretório.

Duas soluções

Como esse tipo de coisa é comum, o shell possui notação de chaves:

$ echo "${servername}_log_20150312"
SomeName_log_20150312

Outras formas de separar o nome dos caracteres que se seguem são possíveis:

$ echo "$servername""_log_20150312"
SomeName_log_20150312

Documentação

A partir de man bash , um nome de variável pode conter qualquer combinação de caracteres alfanuméricos e sublinhados, mas deve começar com um caractere alfabético:

   name   A word consisting only of alphanumeric characters  and  underscores,  and
          beginning  with  an alphabetic character or an underscore.  Also referred
          to as an identifier.

POSIX limita a dependência da implementação de nomes de variáveis. Embora exija que os shells aceitem alfanuméricos e sublinhados em nomes, aparentemente dá aos shells a opção de aceitar qualquer coisa, exceto = e NUL.

    
por 13.03.2015 / 20:06
1

@ john1024 apontou corretamente o bug no meu script. Ao executar o comando grep, o shell estava procurando a variável $servername_log_20150312 em vez de apenas $servername como pretendido.

O deslocamento como "$servername" resolveu o problema.

Eu achei que era o grep agindo estranhamente porque eu vi todos os nomes de servidores esperados na entrada para o grep. Mas isso foi um truque porque na verdade não estava conseguindo encontrar a variável $servername_log_20150312 e padronizando a busca em todo o diretório. Como aconteceu, todos os nomes de servidores desejados apareceram no diretório antes que o limite máximo de argumentos do grep fosse alcançado, obscurecendo ainda mais a verdadeira causa.

    
por 13.03.2015 / 19:47