Solução em TXR Lisp:
txr -e '(each ((line (get-lines)))
(set [line (rest (where (op eql #\,) line))]
(repeat ";"))
(put-line line))' < input
"Para cada linha, defina o resto dos lugares (ou seja, todos, mas o primeiro lugar), onde essa linha é igual a vírgula, a um ponto-e-vírgula. Saída da linha."
Transcrição anotada da sessão de ouvinte interativo de fundo:
$ txr
This is the TXR Lisp interactive listener of TXR 148.
Use the :quit command or type Ctrl-D on empty line to exit.
Lista de infinitas lazy de ponto e vírgula:
1> (take 3 (repeat ";"))
(#\; #\; #\;)
Ligação variável:
2> (let ((a "a,b,c"))
a)
"a,b,c"
A notação de suporte extrai índices:
3> (let ((a "a,b,c"))
[a '(1 3)])
",,"
A função
where
extrai posições em que o predicado é verdadeiro:
4> (let ((a "a,b,c"))
(where (op eql #\,) a))
(1 3)
Atribuir uma sequência a um lugar denotado por notação quadrada com a lista de índices faz com que esses índices sejam substituídos por elementos da sequência, não levando mais do que elementos suficientes para satisfazer os índices:
5> (let ((a "a,b,c"))
(set [a '(1 3)] (repeat ";"))
a)
"a;b;c"
Calcule dinamicamente os índices com where
:
6> (let ((a "a,b,c"))
(set [a (where (op eql #\,) a)] (repeat ";"))
a)
"a;b;c"
Cortar o primeiro índice com rest
, para evitar a primeira vírgula com ponto-e-vírgula:
7> (let ((a "a,b,c"))
(set [a (rest (where (op eql #\,) a))] (repeat ";"))
a)
"a,b;c"
Teste com outras strings. Ops, ""
não é modificável:
8> (let ((a ""))
(set [a (rest (where (op eql #\,) a))] (repeat ";"))
a)
** replace-str: "" of type lit is not a modifiable string
** during evaluation of form (sys:dwim-set a #:g0145 #:g0144)
** ... an expansion at expr-8:2 of (sys:dwim-set (#:g0146) #:g0145
#:g0144)
** which is located at expr-8:2
Tente novamente:
9> (let ((a (copy "")))
(set [a (rest (where (op eql #\,) a))] (repeat ";"))
a)
""
String sem vírgulas:
10> (let ((a "a"))
(set [a (rest (where (op eql #\,) a))] (repeat ";"))
a)
"a"
String com apenas uma vírgula: nenhuma substituição ocorre.
11> (let ((a "a,b"))
(set [a (rest (where (op eql #\,) a))] (repeat ";"))
a)
"a,b"