Para usos simples, você pode fazer assim:
newText=${text/SEARCH/replacement}
como é descrito aqui , mas para expressões mais complexas sed é o caminho a percorrer como alex descrito anteriormente.
Na programação, muitas vezes vemos o uso de Expressões regulares .
Uma das formas mais comuns é:
newText = text.replace( /regex/, 'replacementString' )
Se stdin for text
e stdout for newText
, qual seria o equivalente da bash ao código acima?
Para usos simples, você pode fazer assim:
newText=${text/SEARCH/replacement}
como é descrito aqui , mas para expressões mais complexas sed é o caminho a percorrer como alex descrito anteriormente.
man sed
sed s/regex/replacementString/g
A resposta mais direta é o comando sed s
. Você precisa converter a sintaxe regexp em Expressões regulares básicas , e a substituição será aplicada sucessivamente em cada linha. Você pode usar a
para se referir a grupos entre parênteses na string original. Adicione o modificador
g
para substituir todas as ocorrências; caso contrário, apenas a primeira ocorrência será substituída.
sed -e 's/basic regexp/replacement string/g'
Um utilitário mais flexível é awk . Ele também processa sua entrada linha por linha por padrão, mas você pode alterar o separador de registro com -vRS=…
(padrão awk quer um único caractere ou um valor vazio para significar duas ou mais novas linhas; Gawk (a versão GNU) aceita um regular expressão). A função sub
executa uma única substituição e gsub
substitui todas as ocorrências. A string de substituição é interpretada literalmente, exceto por \
e &
; Se você quiser se referir a grupos entre parênteses, poderá usar as funções match
e subtring
.
awk '{gsub(/regexp/, "replacement string")}'
O Bash tem suporte interno para correspondência de expressões regulares: [[ text =~ regexp ]]
. Você pode construir um texto de substituição usando substrings correspondidas armazenadas na matriz BASH_REMATCH
. Use read
ou cat
para obter a entrada e printf
para emitir a saída. O pseudocódigo a seguir executa várias substituições (aviso, não testado; o código deve executar várias substituições da esquerda para a direita, como é normal, espero ter acertado).
# The end marker must not have a prefix that is a suffix of a match of the regexp,
# and must not start or end with a newline
end_marker='EOF'
text=$(cat; echo "$end_marker")
while [[ $text =~ regexp(.*)$ ]]; then
printf %s%s "${text%"$BASH_REMATCH[0]"}" "replacement string"
text=$BASH_REMATCH[$#BASH_REMATCH]
fi
done
printf %s "${text%"$end_marker"}"
(Algumas palavras de explicação: o marcador final é para evitar que novas linhas sejam removidas pela substituição do comando. ${text%"$BASH_REMATCH[0]"}
extrai a parte do texto que veio antes da correspondência. Observe que não podemos usar ^(.*)
no início do regexp ou teríamos o último jogo em vez do primeiro. Após a partida, nós iteramos sobre o sufixo. Finalmente, imprimimos a sobra inigualável, menos o marcador final.)
Se você estiver satisfeito com as habilidades de correspondência de caracteres curinga e de texto de substituição limitada, o bash também terá ${variable/pattern/replacement}
. Duplique a primeira barra para substituir todas as ocorrências. Os padrões têm o poder das expressões regulares (mas com uma sintaxe incomum) se a opção extglob
estiver definida.
você pode usar ferramentas como sed
e awk
, mas na minha opinião elas são muito antiquadas e úteis apenas para tarefas definidas de forma restrita.
uma aposta melhor é redirecionar STDIN para um perl one-liner ou script. O suporte a regex do perl é tão bom que a maioria das outras linguagens agora suporta alguma compatibilidade com elas. Existem até a2p
e s2p
ferramentas para transformar sed e awk diretamente em perl. O uso do perl permite que você use a totalidade do CPAN para ajudá-lo a resolver seus problemas.
e se você não gosta de perl, você pode usar python em uma capacidade similar.
Tags bash regular-expression