
Eu tenho esse script que atribuo a um atalho de teclado para simular a colagem através do clique do meio:
#!/bin/bash
aa=0
for randstring in `xsel`
do
if [[ "$randstring" =~ [ěščřžýáíéúůóťďň] ]]
then
xxx=`xsel|sed 's/ě/\\\[ecaron]/g' |sed 's/š/\\\[scaron]/g' |sed 's/č/\\\[ccaron] g' |sed 's/ř/\\\[rcaron]/g' |sed 's/ž/\\\[zcaron]/g' |sed 's/ý/\\\[yacute]/g' |sed 's/á/\\\[aacute]/g' |sed 's/í/\\\[iacute]/g' |sed 's/é/\\\[eacute]/g' |sed 's/ú/\\\[uacute]/g' |sed 's/ů/\\\[uring]/g' |sed 's/ó/\\\[oacute]/g' |sed 's/ď/\\\[dcaron]/g' |sed 's/ň/\\\[ncaron]/g' |sed 's/ť/\\\[tcaron]/g' |sed ':a;N;$!ba;s/\n/\\n/g'`
xvkbd -text "$xxx" 2>/dev/null
aa=1
break
else
aa=0
fi
done
if [[ $aa -eq 0 ]]
then
xsel | xvkbd -file - 2>/dev/null
fi
Eu uso -text
xvkbd quando o texto está em tcheco (meu idioma) porque xvkbd não entende diacríticos como ě, mas apenas na forma como \[ecaron]
. Agora, com esta opção, se houver uma nova linha int xsel, ela não será impressa com xvkbd. No entanto, quando eu faço
xx="---8<-----\nToday date is: $(date +%Y%m%d)\n---8<-----"
xvkbd -text "$xx" 2>/dev/null
Novas linhas são impressas.
Suspeito que o problema esteja na última expressão sed sed ':a;N;$!ba;s/\n/\\n/g'
, mas não sei como melhorá-la. Eu acho que preciso cuidar \n
de alguma forma?
Responder1
EDIT: Eu encontrei o problema, mas o resto ainda pode valer a pena ler quando você realmente quiser uma nova linha `...
Você está faltando um extra \\
ou até mesmo apenas\
sed ':a;N;$!ba;s/\n/\\\\n/g'`
MAIS INFORMAÇÕES: Em relação à questão de $( )
vs backquotes para command substitution
, mencionei um comentário que fiz para esta questão, aqui está um trecho de man bash
.
When the old-style backquote form of substitution is used, backslash
retains its literal meaning except when followed by $, `, or \. The
first backquote not preceded by a backslash terminates the command sub‐
stitution. When using the $(command) form, all characters between the
parentheses make up the command; none are treated specially.
--Postagem Original--
Não imprimirá o último \n
, mas adiciona intermediário \n
em $xx
...
Aqui está uma versão simplificada de sua última sed
chamada:
printf '%s\n' 'a\[ecaron]' b c '\[rcaron]d' |
sed ':a;N;$!ba;s/\n/\\n/g'
Saída:
a\[ecaron]\nb\nc\n\[rcaron]d
A razão pela qual não tem um final \n
(no exemplo acima) é que simplesmente não haverá um caractere de nova linha no espaço padrão para a última linha (apenas aqueles de finais de linha anteriores, via N
, estarão lá) ... sed
posteriormente produzirá o caractere de nova linha final ao sair, mas mesmo assim, ele será engolido pelo xx=$(command substitution)
by $( )
ou backticks
...
Para incluir um final \n
, é necessária apenas uma substituição final.
sed ':a;N;$!ba;s/\n/\\n/g;s/$/\\n/'
Ou é o caso de você não estar conseguindo nem os intermediários \n
?
Apenas uma observação: você não precisa ter muitossedschamando tantos processos. Você pode concatená-los via ;
(dois pontos), por exemplo. sed 's/ě/\\\[ecaron]/g; s/š/\\\[scaron]/g; ....
ou nem mesmo usar dois pontos e apenas colocar cada expressão de substituição em uma nova linha .. o que permite que eles se alinhem perfeitamente ...