
Tengo este script que asigno a un atajo de teclado para simular el pegado mediante clic central:
#!/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
Lo uso -text
con xvkbd cuando el texto está en checo (mi idioma) porque xvkbd no entiende signos diacríticos como ě sino solo en forma como \[ecaron]
. Ahora, con esta opción, si hay una nueva línea int xsel, no se imprime con xvkbd. Sin embargo, cuando lo hago
xx="---8<-----\nToday date is: $(date +%Y%m%d)\n---8<-----"
xvkbd -text "$xx" 2>/dev/null
Las nuevas líneas se imprimen.
Sospecho que el problema está en la última expresión sed sed ':a;N;$!ba;s/\n/\\n/g'
, pero no sé cómo mejorarla. ¿Creo que necesito cuidarlos \n
de alguna manera?
Respuesta1
EDITAR: Encontré el problema, pero aún así vale la pena leer el resto para cuando realmente quieras una nueva línea final `...
Te falta un extra \\
o incluso solo\
sed ':a;N;$!ba;s/\n/\\\\n/g'`
MÁS INFORMACIÓN: Respecto al tema de $( )
vs backquotes para command substitution
, mencioné un comentario que puse a esta pregunta, aquí hay un extracto 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.
--Publicación original--
No imprimirá el último \n
pero agrega intermedio \n
en $xx
...
Aquí hay una versión simplificada de su última sed
llamada:
printf '%s\n' 'a\[ecaron]' b c '\[rcaron]d' |
sed ':a;N;$!ba;s/\n/\\n/g'
Producción:
a\[ecaron]\nb\nc\n\[rcaron]d
La razón por la que no tiene un final \n
(en el ejemplo anterior) es que simplemente no habrá un carácter de nueva línea final en el espacio de patrón para la última línea (solo N
estarán allí los de finales de línea anteriores, a través de ) ... sed
posteriormente generará el carácter de nueva línea final cuando salga, pero aun así, será devorado por xx=$(command substitution)
by $( )
o backticks
...
Para incluir una final \n
, solo necesita una sustitución final.
sed ':a;N;$!ba;s/\n/\\n/g;s/$/\\n/'
¿O es que no estás obteniendo ni siquiera los \n
s intermedios?
Sólo una nota al margen: no es necesario tener innumerablessedsllamando a tantos procesos. Puede concatenarlos mediante ;
(dos puntos), por ejemplo. sed 's/ě/\\\[ecaron]/g; s/š/\\\[scaron]/g; ....
o ni siquiera usar los dos puntos y simplemente poner cada expresión de sustitución en una nueva línea... lo que les permite alinearse muy bien...