Correspondência de padrões de shell vs. ocorrências de expressões regulares [duplicado]

0

Sou relativamente novo no Unix e me deparei com uma curiosidade. Algumas construções de shell, como case ou find , empregam correspondência de padrões, mas não são exatamente regex. Outros comandos, como ed , sed , vi e awk , usam expressões regulares para correspondência de padrões. Alguém poderia listar quais comandos shell (builtins, programas) usam regex e quais usam o outro tipo de correspondência de padrões?

    
por Martin 23.09.2014 / 17:12

2 respostas

1

case usa globs , que é um sistema de correspondência de padrões muito simples, semelhante a expressões regulares. Algumas ferramentas, como find , suportam ambas (via -name e -regex neste caso). Mas o caso é ainda mais complicado: existem diferentes sabores de expressões regulares . Algumas ferramentas suportam uma, algumas várias. Você só precisa verificar, por combinação de ferramenta e versão, o que a página man ou outra documentação de referência diz (e, mesmo assim, pode ser difícil descobrir). Uma lista de referência seria gigantesca e não acho que seria uma resposta muito útil.

    
por 23.09.2014 / 17:20
1

Eu acho que a principal diferença entre usar expressões regulares é se elas precisam corresponder a string inteira ou não. Em case , find e alguns outros comandos bash você tem que combinar toda a string, enquanto em sed , awk , grep e assim por diante você tem que combinar com qualquer parte da string. Além disso, são semelhantes, mas, claro, não são idênticos.

Por exemplo, quando você usa uma expressão regular em case instruções do bash shell, supõe-se que sua expressão regular descreva toda a string. Ou seja (Estou usando exemplo aqui )

case $SERVER in
db-[0-9]+\.host\.com) echo "DB server"
;;
*)echo "Unknown server"
;;
esac

Você pode ver que db- [0-9] +. host.com descreve a string, que começa com "db-", depois tem um ou mais dígitos e termina com ".host.com", então db-1.host.com corresponderá, enquanto xdb-1.host.com não.

Agora, se você olhar para sed e escrever o padrão de pesquisa de maneira semelhante

echo "xdb-1.host.com"| sed -nr '/db-[0-9]+\.host\.com/p'

sed , ao contrário do comando case , imprime a linha xdb-1.host.com, porque pode encontrar o padrão de pesquisa DENTRO desta cadeia. Então, a ideia não é combinar a string inteira, mas encontrar qualquer ocorrência do padrão.

De maneira semelhante, se você usar o comando regexp no comando find , a string inteira deverá corresponder. Por exemplo,

find / -regextype sed -regex ".*\.dat"

encontrará todos os arquivos que possuem a extensão dat. Mas se você tentar fazer a mesma pesquisa com sed ,

find / | sed -nr '/.*\.dat/'

ele corresponderá a todos os arquivos, que contêm a string ".dat" no nome do arquivo.

Existem também algumas pequenas diferenças de sintaxe, é claro. Por exemplo, se você fizer

find / -name "*.dat"

este também é um tipo de expressão regular, onde * significa "qualquer número de símbolos arbitrários", mas no sentido estrito você deve escrever ". *", onde "." significa qualquer símbolo, e * significa qualquer número de símbolos do tipo ".", juntos significam qualquer número de símbolos.

    
por 23.09.2014 / 17:56