Retorne uma partida regex em um script bash, em vez de substituí -lo
Pergunta
Eu só quero corresponder a algum texto em um script bash, tentei usar o SED, mas não consigo fazer com que a saída da partida em vez de substituí -lo por algo.
echo -E "TestT100String" | sed 's/[0-9]+/dontReplace/g'
Que será produzido: testtdontreplacestring
O que não é o que eu quero, eu quero que seja produzido: 100
Idealmente, eu gostaria que ele colocasse todas as partidas em uma matriz.
Editar: a entrada de texto está chegando como uma string:
newName()
{
#Get input from function
newNameTXT="$1"
if [[ $newNameTXT ]]; then
#Use code that im working on now, using the $newNameTXT string.
fi
}
Solução
echo "TestT100String" | sed 's/[^0-9]*\([0-9]\+\).*/\1/'
echo "TestT100String" | grep -o '[0-9]\+'
O método que você usa para colocar os resultados em uma matriz depende um pouco de como os dados reais estão sendo recuperados. Não há informações suficientes em sua pergunta para poder guiá -lo bem. No entanto, aqui está um método:
index=0
while read -r line
do
array[index++]=$(echo "$line" | grep -o '[0-9]\+')
done < filename
Aqui está outra maneira:
array=($(grep -o '[0-9]\+' filename))
Outras dicas
Você pode fazer isso puramente em bash usando o suporte quadrado duplo [[ ]]
Operador de teste, que armazena resulta em uma matriz chamada BASH_REMATCH
:
[[ "TestT100String" =~ ([0-9]+) ]] && echo "${BASH_REMATCH[1]}"
Puro Bash. Use a substituição de parâmetros (sem processos e tubos externos):
string="TestT100String"
echo ${string//[^[:digit:]]/}
Remove todos os não-dígitos.
Use Grep. Sed é um editor. Se você deseja corresponder apenas a um regexp, o grep é mais do que suficiente.
usando AWK
linux$ echo -E "TestT100String" | awk '{gsub(/[^0-9]/,"")}1'
100
Eu não sei por que ninguém nunca usa expr
: é portátil e fácil.
newName()
{
#Get input from function
newNameTXT="$1"
if num=`expr "$newNameTXT" : '[^0-9]*\([0-9]\+\)'`; then
echo "contains $num"
fi
}
Sei que este é um tópico antigo, mas eu a venha nas mesmas pesquisas e encontrei outra grande possibilidade aplicar uma regex em uma string/variável usando grep:
# Simple
$(echo "TestT100String" | grep -Po "[0-9]{3}")
# More complex using lookaround
$(echo "TestT100String" | grep -Po "(?i)TestT\K[0-9]{3}(?=String)")
Com o uso, as expressões de pesquisa de recursos Lookound podem ser estendidas para uma melhor correspondência. Onde (?i)
indica o padrão antes do padrão pesquisado (lookahead),\K
indica o padrão de pesquisa real e (?=)
Contém o padrão após a pesquisa (lookbehind).
https://www.regular-expressions.info/lookAround.html
O exemplo dado corresponde à mesma forma que o pcre regex TestT([0-9]{3})String
Bem, o SED pelo S/"Pattern1"/"Pattern2"/G apenas substitui globalmente todos os padrões1s ao padrão 2.
Além disso, sed, enquanto imprimirá a linha inteira por padrão. Eu sugiro fazer a instrução para um comando de corte e tentar extrair os números que você deseja:
Se você estiver procurando apenas para usar o sed, use o TRE:
sed -n 's/.*\(0-9\)\(0-9\)\(0-9\).*/\1,\2,\3/g'.
Eu não tento executar o comando acima, portanto, verifique se a sintaxe está certa. Espero que isso tenha ajudado.
Usando apenas a casca de festa
declare -a array
i=0
while read -r line
do
case "$line" in
*TestT*String* )
while true
do
line=${line#*TestT}
array[$i]=${line%%String*}
line=${line#*String*}
i=$((i+1))
case "$line" in
*TestT*String* ) continue;;
*) break;;
esac
done
esac
done <"file"
echo ${array[@]}