%20substituindo%20todas%20as%20ocorr%C3%AAncias%20de%20um%20caractere%20enquanto%20exclui%20o%20%C3%BAltimo%3F.png)
Estou lutando com o seguinte. Estou usando comandos como este no meu terminal Mac para testar meu regex:
echo 'inputstring' | sed (-E) '/s///g'
Estou tentando criar uma regex que:
- se e somente se uma palavra terminar com a letra 'o', então:
- exclui este 'o' final de palavra
- substitui todas as ocorrências da letra 'i' por 'a' nesta palavra
Neste caso, a string de entrada é filo fililo felo fale
e a saída esperada éfal falal fel fale
Posso fazer uma regex que faça tanto a exclusão quanto a substituição, mas não vejo como combiná-las. Se eu colocar uma semicoluna entre eles, não vejo como colocar a parte condicional.
Também estou tendo problemas para definir a posição do 'fim da palavra'. Eu usei \b
, mas parece não funcionar (ao contrário $
do final da string).
Responder1
Eu não usaria sed
para isso, mas se isso for um exercício para aprender sed
, faça um loop assim:
sed -E 's/$/ /
:a
s/i([[:alnum:]]*o[^[:alnum:]])/a\1/
ta
s/([[:alnum:]]*)o([^[:alnum:]])/\1\2/
ta
s/ $//'
- Na primeira linha adiciono um espaço em branco no final, para que possamos tratar o final da linha como qualquer final de palavra. A última linha remove esse espaço em branco posteriormente.
- O
s
comando na linha 3 procura ocorrências dei
em uma palavra que termina como
e a substitui pora
. Ot
comando retorna à marca:a
para repetir isso para todas as palavras comi
terminaçãoo
. - Agora a quinta linha remove o final
o
e outro loop. Observe que de uma palavra que termina comoo
, ambos serão removidos; não está claro se isso é desejado.
Apenas para referências, utilizo uma sed
versão que suporta a o
opção do s
comando que significa apenas preservar a parte correspondente e jogar fora o resto. Também conhece o \h
substituto para substituir pelo conteúdo do espaço de espera. Isso torna a tarefa de uma linha:
sed -E ':a;h;s/([[:alnum:]]*)o($|[^[:alnum:]])/\1\2/o;T;y/i/a/;x;s//\h/;ba'
Responder2
Eiseria mais preciso e flexível para tal caso:
awk '{ for(i=1;i<=NF;i++)
if ($i~/o$/) { sub(/o$/,"",$i); gsub("i","a",$i) } }1' <<<"filo fililo felo fale"
A saída:
fal falal fel fale
AlternativaPitãoabordagem de linha de comando:
python -c 'import sys,re; s = sys.stdin.read().strip();
print(re.sub(r"\b(\S+)o\b", lambda m: m.group(1).replace("i","a"), s))' <<<"filo fililo felo fale"
fal falal fel fale
Responder3
Não tenho certeza se isso é possível sed
(suspeito que provavelmente não), mas é muito fácil de fazer com Python! Aqui está um script que faz exatamente o que você deseja:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""modify_strings.py"""
import sys
import re
import fileinput
# Iterate over lines of input
# (either read from files or from stdin)
for line in fileinput.input():
# Split each line into tokens and preserve whitespace
tokens = re.split(r'(\s+)', line)
# Iterate over tokens
for token in tokens:
# If a word ends in 'o' then
# perform the desired transformation
if token.endswith('o'):
token = token[:-1].replace('i', 'a')
# Print out each token
sys.stdout.write(token)
Você pode executá-lo assim:
echo 'filo fililo felo fale' | python modify_strings.py
E produz a seguinte saída (conforme desejado):
fal falal fel fale
Se você realmente deseja sed
se envolver, provavelmente poderá conseguir o que deseja aumentando-o com um pouco de script de shell. Isso pode ser parecido com o seguinte bash
script:
#!/usr/bin/env bash
# modify-strings.bash
for word in "$@"; do
if grep -q 'o$' <<<"${word}"; then
echo -n "${word} " | sed -e 's/i/a/g' -e 's/o$//';
else
echo -n "${word} ";
fi;
done
echo
Você chamaria esse script assim:
bash modify-strings.bash filo fililo felo fale