Se você puder confiar nas expressões regulares internas do Bash (ou seja, no operador =~
) e nas variáveis do array, você pode usar algo assim:
#!/bin/bash
W1=( $( echo "$1" | sed "s/./\n&/g" | sort -u ) )
W2="$2"
set ${W1[*]}
while [[ ! -z "$1" ]]; do
if [[ "$W2" =~ "$1" ]]; then
printf "$1 "
fi
shift
done
printf "\n"
A primeira linha cria uma matriz que contém todos os caracteres contidos em $1
. Em seguida, $2
é salvo e, em seguida, os parâmetros posicionais são definidos para os valores de $W1
elements. Então, cada caractere (agora parâmetro posicional) é comparado com a segunda palavra salva e, se a correspondência for encontrada, será impressa. Por último, os parâmetros posicionais são deslocados para que o loop continue com o próximo caractere.
Conceitos que você pode ver aqui: trabalhando com uma matriz, capturando a saída de um comando em uma variável, alterando argumentos posicionais, loop e instruções condicionais.
Se você quiser fazê-lo simplesmente, você pode querer considerar, por exemplo, este (na verdade, é uma divisão de uma linha para maior legibilidade):
#!/bin/bash
printf "$1" \
| sed "s/./\n&/g" | sort -u \
| grep -F "$( printf "$2" | sed 's/./&\n/g' | sort -u )"
Os combos sed | sort -u
apenas dividem as palavras em um único caractere por formulários de linha. grep -F
trata o parâmetro (aqui a segunda palavra dividida) como sequências fixas que devem ser correspondidas na entrada e, portanto, tenta corresponder a cada caractere em $1
com cada caractere em $2
. Em situações reais, você provavelmente removeria a segunda combinação de sort | uniq
, já que "palavras" geralmente são curtas e qualquer ganho de desempenho seria eliminado pela geração de dois processos adicionais. No entanto, como $2
fica maior (centenas ou milhares de linhas), você definitivamente quer fazer qualquer otimização possível.
Você também pode substituir o comando sed
por fold -w 1
, que faz quase o mesmo (é mais curto para digitar, mas o comando sed
s
é o canivete suíço de processamento de texto).