Usando grep , tee e rev , crie uma pequena função complicada cheia de bash -isms:
dqs() { a=${2:-123456789} ; [ "$1" -ge 2 ] &&
grep -iF "$(eval eval printf '%s\\n' \$\{a:\{0..$((${#a}-$1))\}:$1\} |
tee >(rev) )"
}
Teste:
dqs 5 < data.log
1234567
dqs 4 < data.log
1234
7654
1234567
dqs 3 < data.log
12365
349874
1234
7654
08767
1234567
Como funciona:
printf imprime uma lista de sequências do tamanho desejado, (como 123 , 234 , etc. ), tee acrescenta uma imagem espelho ( ou seja, da direita para a esquerda ou para trás) usando rev , então grep -f <(...) pesquisa a entrada padrão para qualquer item dessa lista.
Para fazer essa lista de seqüências, geralmente seria necessário um loop, ou seq , ou até mesmo ambos, mas aqui nós trapaceitamos usando bash expressão de sequência , combinada com um expansão da substring e algumas aritmética . Mas é impossível, porque o interpretador bash não pode executá-los na ordem desejada. Portanto, eval eval e vários% estratégicos\\ s são usados para forçar o bash a fazer as coisas na ordem correta.
O [ "$@" -gt 0 ] && não é funcionalmente necessário aqui, mas é mais seguro tê-lo. Ele garante que dqs tenha um e apenas um parâmetro numérico, ou grep não será executado. Isso impede que eval eval faça qualquer coisa mal .
Bônus: Adicionar um segundo argumento pode alterar o 123456789 para qualquer outra sequência e o código ainda deve funcionar. Por exemplo, dqs 4 123456789ABCDEF procuraria sequências hexadecimais de quatro dígitos (e sequências inversas) e dqs 3 $(printf %s {a..z}) procuraria sequências alfabéticas de três letras.
# search 'man bash' for the three most popular words
# that have 3 three char alphabetic runs
man bash | tr ' ' '\n' | sort | uniq -c | sort -gr |
dqs 3 $(printf '%s' {a..z}) | head -3
Saída:
92 first
76 default
38 environment