Aquí hay una muy larga, enrevesada y probablemente innecesaria sed
, pero aquí es, sin embargo, porque es divertido:
sed -re 'h; s/^([0-9]*) *(.*)/\1\n/; :1 s/(.)(.*\n)/\2\1/;t1; s/.//; s/^(.*)$/\(\1\)/; x;s/([0-9]{3})(.*)/\2/;x;G;s/\n//'
Esto funciona así:
# pretend 214 4234-5555 is the current line
h; # copy the current line into hold space
s/^([0-9]*) *(.*)/\1\n/; # keep only first 3 numbers, 214
:1 s/(.)(.*\n)/\2\1/;t1; s/.//; # reversing string in sed,
# see notes below; 214 becomes 412
s/^(.*)$/\(\1\)/; # After string is reversed, add brackets; (412)
x;s/([0-9]{3})(.*)/\2/; # swap hold and pattern buffer,
# delete first 3 chars;
# pattern space now is 4234-5555
x;G;s/\n// # swap again, append hold buffer to pattern buffer;
# now pattern buffer is (412) 4234-5555;
# finally delete newline; we get (412) 4234-5555
Y así es como se ve en acción:
$ printf "214 4234-5555\n123 3333\n" | sed -re 'h; s/^([0-9]*) *(.*)/\1\n/; :1 s/(.)(.*\n)/\2\1/;t1; s/.//; s/^(.*)$/\(\1\)/; x;s/([0-9]{3})(.*)/\2/;x;G;s/\n//'
(412) 4234-5555
(321) 3333
Nota:Inversión de cadenas encontrada originalmente en comentario de Stephane Chazelas
Если я сделаю следующее со значением INPUT
в кавычках, это сработает:
> INPUT='mark!slash\ending\'
> SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')
> echo $SAFE_INPUT
mark\!slash\\ending\\
Заметьте, это точная копия вашего скрипта с INPUT=
добавленным мной.