Tenho a seguinte lista de itens:
bigBone
fishMarket
dogCollar
...
Preciso gerar um mapeamento de dois caracteres como este:
bigBone -> bb
fishMarket -> fm
dogCollar -> dc
...
Como posso criar o mapeamento acima usando sed
?
Eu tentei algo como:
sed -i -r 's/^([a-z]{1})[a-z]+([A-Z]{1})[a-zA-Z]+/ -> \1\L\2/' file
Eu viessa questão, mas não tenho certeza de como incorporar o conceito aqui. Obrigado.
Responder1
Se bem entendi, você deseja manter a linha inteira e apenas acrescentar algo:
sed -r 's/^([a-z]{1})([a-z]+)([A-Z]{1})([a-zA-Z]+)$/\1\2\3\4 -> \1\L\3/' file
editar:
devnull teve que me lembrar que existe uma solução fácil para isso:
sed -r 's/^([a-z]{1})[a-z]+([A-Z]{1})[a-zA-Z]+/& -> \1\L\2/' file
Ou um pouco mais elegante (do que minha primeira tentativa):
sed -r '
h
s/^([a-z]{1})[a-z]+([A-Z]{1})[a-zA-Z]+/ -> \1\L\2/
t append
b
: append
H
g
s/\n//' file
Responder2
Usando GNU sed:
sed -r 's/(.)[^[:upper:]]*(.).*/& -> \1\L\2/' inputfile
Para sua opinião, produziria:
bigBone -> bb
fishMarket -> fm
dogCollar -> dc
Responder3
Para generalizar para fooBarBaz -> fbb
, abCdEfGh -> aceg
, com GNU sed
:
sed -r 's/(.)(.*)/\1\n\2 -> \L\1/;:1
s/\n([^[:upper:]]*([[:upper:]]))(.*)/\1\n\3\L\2/;t1;s/\n//'
POSIX sed
não tem \L
. Portanto, de forma portável, você teria que recorrer ao uso y
e inserir manualmente todos os caracteres que deseja converter em letras minúsculas. Algo como:
LC_ALL=C sed '/^\([[:alpha:]]\).*/{
h;s//\1/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;G
s/\(.\).\(.\)\(.*\)/\2\
\3 -> \1/;:1
/.*\n[^A-Z]*\([A-Z]\).*/{h;s//\1/
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;G
s/^\(.\)\n\(.*\)\n\([^A-Z]*[A-Z]\)\(.*\)/\2\3\
\4\1/;t1
}
s/\n//;}'
Responder4
Esta resposta é semelhante à de @devnull,
$ sed 's/\(.\).*\([A-Z]\).*/& -> \1\L\2/g' file
bigBone -> bb
fishMarket -> fm
dogCollar -> dc