Cómo search, replace y agregar un patrón al final de cada línea

Tengo la siguiente list de artículos:

bigBone fishMarket dogCollar ... 

Necesito generar un mapeo de dos caracteres como este:

 bigBone -> bb fishMarket -> fm dogCollar -> dc ... 

¿Cómo puedo crear el mapeo anterior utilizando sed ?

He intentado algo como:

 sed -i -r 's/^([az]{1})[az]+([AZ]{1})[a-zA-Z]+/ -> \1\L\2/' file 

Vi esta pregunta , pero no estoy seguro de cómo incorporar el concepto aquí. Gracias.

Solutions Collecting From Web of "Cómo search, replace y agregar un patrón al final de cada línea"

Si te entiendo correctamente, entonces debes mantener toda la línea y anexar algo:

 sed -r 's/^([az]{1})([az]+)([AZ]{1})([a-zA-Z]+)$/\1\2\3\4 -> \1\L\3/' file 

editar :

Devnull tuvo que recordarme que hay una solución fácil para esto:

 sed -r 's/^([az]{1})[az]+([AZ]{1})[a-zA-Z]+/& -> \1\L\2/' file 

O, un poco más elegante (que mi primer bash):

 sed -r ' h s/^([az]{1})[az]+([AZ]{1})[a-zA-Z]+/ -> \1\L\2/ t append b : append H g s/\n//' file 

Usando GNU sed:

 sed -r 's/(.)[^[:upper:]]*(.).*/& -> \1\L\2/' inputfile 

Para su input, produciría:

 bigBone -> bb fishMarket -> fm dogCollar -> dc 

Para generalizar a fooBarBaz -> fbb , abCdEfGh -> aceg , con 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 no tiene \L De manera portátil, tendría que recurrir al uso de y ingresar manualmente todos los caracteres que desea convertir a minúsculas. Algo como:

 LC_ALL=C sed '/^\([[:alpha:]]\).*/{ h;s//\1/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;G s/\(.\).\(.\)\(.*\)/\2\ \3 -> \1/;:1 /.*\n[^AZ]*\([AZ]\).*/{h;s//\1/ y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;G s/^\(.\)\n\(.*\)\n\([^AZ]*[AZ]\)\(.*\)/\2\3\ \4\1/;t1 } s/\n//;}' 

Aquí está con un script compatible con POSIX. No sabía que POSIX sed deja el comportamiento de s///[n]g especificar, pero, por supuesto , no es un comportamiento bien definido. De todos modos, es fácil de manejar sin él, simplemente no me gusta usar demasiadas references, si puede ser ayudado, por lo general.

 sed '/^[az]*[AZ].*$/{ h s/\(.\)[^AZ]*/\1/g y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ H ; gs/\n/ -> / }' <<\DATA bigBone fishMarket dogCollar DATA #OUTPUT bigBone -> bb fishMarket -> fm dogCollar -> dc 

Esta respuesta es similar a @ devnull's,

 $ sed 's/\(.\).*\([AZ]\).*/& -> \1\L\2/g' file bigBone -> bb fishMarket -> fm dogCollar -> dc 

Si puede usar perl , intente:

 $ perl -MList::Util=first -F// -aple '$_ .= " -> ".$F[0].lc(first{ord() < 97} @F)' file bigBone -> bb fishMarket -> fm dogCollar -> dc