1

У меня есть этот сценарий, который я назначаю сочетания клавиш для имитации вставки через средний щелчок:

#!/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 ':a;N;$!ba;s/\n/\\n/g' , но я не знаю, как сделать это лучше. Я думаю, что мне нужно как-то позаботиться о \n s?

1 ответ1

1

РЕДАКТИРОВАТЬ: Я нашел проблему, но остальное, возможно, все еще стоит прочитать, когда вы действительно хотите завершающий перевод строки `...

Вам не хватает лишнего \\ или даже просто \

  sed ':a;N;$!ba;s/\n/\\\\n/g'`  

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Что касается вопроса о $( ) против обратных кавычек для 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 , будет быть там) ... sed будет впоследствии выводить последний символ новой строки при выходе, но даже в этом случае он будет сожжен xx=$(command substitution) либо $( ) либо backticks ...

Чтобы включить финал \n , нужна только одна финальная замена.

sed ':a;N;$!ba;s/\n/\\n/g;s/$/\\n/'

Или это тот случай, когда вы не получаете даже промежуточных \n s?


Просто примечание: вам не нужно иметь множество seds, вызывающих столько процессов. Вы можете объединить их через ; (двоеточие), например. sed 's/ě/\\\[ecaron]/g; s/š/\\\[scaron]/g; .... или даже не использовать двоеточия и просто помещать каждое выражение замещения в новую строку ... что позволяет им правильно выстраиваться в очередь ...

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .