Não consigo encontrar uma resposta para isso - desculpe se for uma duplicata.
Estou usando /bin/sh
no BSD ( não no bash!) e estou tentando descobrir a sintaxe da seguinte instrução IF.
Eu tenho duas cláusulas componentes. Escrito como declarações separadas, fica assim:
if [ "$a" == "y" -o "$a" == "Y" ]; then
if printf '%s' "$b" | grep -qE 'SOME_REGEX'; then
# both conditions met: do stuff
fi
fi
Então eu posso usar aninhado if
como uma solução alternativa.
Mas qual sintaxe eu preciso para combiná-los perfeitamente em uma única instrução "if"?
NOTA: Se este shell permitir comparações diretas de correspondência de regex ( [ "$a" =~ REGEX" ]
ou similar) em vez de exigir grep -q
, seria útil saber, mas ainda gostaria de saber como combinar corretamente essas cláusulas como estão, porque algum dia certamente terei uma situação em que estou combinando o conteúdo do arquivo e a segunda instrução é algo como ls -l "$b" | grep -qE 'SOME_REGEX'
, portanto, uma comparação de regex inline não funcionaria ... :)
Eu pessoalmente acho que não há problema em ter uma
if
declaração aninhada aqui, embora eu tivesse usado uma sintaxe ligeiramente modernizada:(observe que
==
é umbash
-ismo)Para combiná-los (torna o IMHO menos legível):
Para expressões regulares básicas
expr
, você pode usar (veja o comentário de Stéphane Chazelas abaixo ):O
/bin/sh
shell geralmente não precisa[[ ... =~ ... ]]
fazer correspondência de expressão regular estendida.Em relação à sua nota no final: Expressões regulares são para correspondência em linhas únicas de texto . Se você tratar nomes de arquivos como texto, desqualificará automaticamente qualquer nome de arquivo que não seja uma única linha de texto, como nomes de arquivos que contenham novas linhas. Se você precisar aplicar correspondência de expressão regular a nomes de arquivos, faça isso com cuidado com os nomes armazenados em uma matriz (
$@
em/bin/sh
), ou use uma implementaçãofind
que suporte o-regex
predicado.Padrões de globbing de nome de arquivo são para nomes de arquivo correspondentes.
Observe que
grep
corresponde a cada linha da entrada, não à entrada como um todo, portanto, geralmente não é adequado para strings arbitrárias. Você pode usarawk
em vez disso (cuidado com expressões regulares estendidas semelhantes às compreendidas porgrep -E
oubash
's[[ string =~ regexp ]]
).Observe que os operadores binários
-a
/ devem ser evitados.-o
[
Eles estão obsoletos pelo POSIX e têm vários problemas. Por exemplo, aqui no FreeBSD:Você pode encurtá-lo
$a
concatenado$b
e adicionar padrão ao regexObserve que grep é uma ferramenta de correspondência de linha, portanto \n no final