为什么当我从 xsel 接收信息时 xkvbd 会吃掉换行符?

为什么当我从 xsel 接收信息时 xkvbd 会吃掉换行符?

我有这个脚本,我将其分配给键盘快捷键以模拟通过鼠标中键单击粘贴:

#!/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

编辑:我发现了这个问题,但是当你确实想要一个尾随换行符时,其余部分可能仍然值得一读......

你缺少一个额外的\\,甚至只是\

  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,才会出现)...... sed随后将在退出时输出最后的换行符,但即便如此,它也会被xx=$(command substitution)by$( )backticks... 吞噬。

要包含最后一个\n,只需进行一次最终替换。

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

还是说你甚至连中级都没有得到\n


补充一点:你不需要有无数塞德斯调用那么多进程。;例如,您可以通过(冒号)将它们连接起来。sed 's/ě/\\\[ecaron]/g; s/š/\\\[scaron]/g; .... 或者甚至不使用冒号,而只是将每个替换表达式放在新行上。这样可以让它们很好地排列起来……

相关内容