
У меня есть этот скрипт, который я назначаю сочетанию клавиш для имитации вставки с помощью среднего щелчка:
#!/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
Я использую -text
с xvkbd, когда текст на чешском языке (мой язык), потому что xvkbd не понимает диакритические знаки, такие как ě, а только в форме \[ecaron]
. Теперь, с этой опцией, если есть новая строка int xsel, она не печатается с xvkbd. Однако, когда я делаю
xx="---8<-----\nToday date is: $(date +%Y%m%d)\n---8<-----"
xvkbd -text "$xx" 2>/dev/null
Переводы строк печатаются.
Подозреваю, что проблема в последнем выражении sed sed ':a;N;$!ba;s/\n/\\n/g'
, но не знаю, как его улучшить. Думаю, что мне нужно \n
как-то позаботиться о s?
решение1
EDIT: Я нашел проблему, но остальное все равно стоит прочитать, когда вам действительно нужен завершающий символ новой строки `...
Вам не хватает лишнего \\
или даже просто\
sed ':a;N;$!ba;s/\n/\\\\n/g'`
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Что касается вопроса $( )
vs обратные кавычки для command substitution
, упомянул комментарий, который я оставил к этому вопросу, вот отрывок из 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.
--Оригинальный пост--
Он не печатает последнее \n
, но добавляет промежуточное \n
в $xx
...
Вот упрощенная версия вашего последнего sed
звонка:
printf '%s\n' 'a\[ecaron]' b c '\[rcaron]d' |
sed ':a;N;$!ba;s/\n/\\n/g'
Выход:
a\[ecaron]\nb\nc\n\[rcaron]d
Причина, по которой он не имеет финального символа \n
(в приведенном выше примере), заключается в том, что в пространстве шаблона для последней строки просто не будет завершающего символа новой строки ( N
там будут только те, что были из предыдущих окончаний строк, via )... sed
впоследствии выведет последний символ новой строки при выходе, но даже в этом случае он будет поглощен xx=$(command substitution)
либо by, $( )
либо backticks
...
Чтобы включить финал \n
, нужна всего одна финальная замена.
sed ':a;N;$!ba;s/\n/\\n/g;s/$/\\n/'
Или это тот случай, когда вы не получаете даже промежуточных \n
знаний?
Просто примечание: вам не нужно иметь бесчисленное количествоsedsвызов такого количества процессов. Вы можете объединить их с помощью ;
(двоеточия), например. sed 's/ě/\\\[ecaron]/g; s/š/\\\[scaron]/g; ....
или даже не использовать двоеточия и просто поместить каждое выражение подстановки на новую строку.. что позволяет им хорошо выстроиться...