Warum frisst xkvbd Zeilenumbrüche, wenn es von xsel gespeist wird?

Warum frisst xkvbd Zeilenumbrüche, wenn es von xsel gespeist wird?

Ich habe dieses Skript, dem ich eine Tastenkombination zuweise, um das Einfügen durch mittleren Klick zu simulieren:

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

Ich verwende -textxvkbd, wenn der Text auf Tschechisch (meiner Sprache) ist, weil xvkbd diakritische Zeichen wie ě nicht versteht, sondern nur in der Form \[ecaron]. Mit dieser Option wird nun, wenn ein Zeilenumbruch in xsel vorhanden ist, dieser nicht mit xvkbd gedruckt. Wenn ich jedoch

xx="---8<-----\nToday date is: $(date +%Y%m%d)\n---8<-----" 
xvkbd -text "$xx"  2>/dev/null

Zeilenumbrüche werden gedruckt.

Ich vermute, das Problem liegt im letzten sed-Ausdruck sed ':a;N;$!ba;s/\n/\\n/g', weiß aber nicht, wie ich es besser machen kann. Ich denke, ich muss mich \nirgendwie um s kümmern?

Antwort1

BEARBEITEN: Ich habe das Problem gefunden, aber der Rest ist möglicherweise trotzdem lesenswert, wenn Sie tatsächlich eine abschließende neue Zeile „...“ möchten.

Ihnen fehlt ein Extra \\oder auch nur\

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

WEITERE INFORMATIONEN: Bezüglich des Problems von $( )vs. Backquotes für command substitutionwurde ein Kommentar erwähnt, den ich zu dieser Frage abgegeben habe. Hier ist ein Auszug aus 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.

--Ursprünglicher Beitrag--

Es druckt nicht das Letzte \n, fügt aber ein Zwischenergebnis \n hinzu $xx...

Hier ist eine vereinfachte Version Ihres letzten sedAnrufs:

printf '%s\n' 'a\[ecaron]' b c '\[rcaron]d' |
   sed ':a;N;$!ba;s/\n/\\n/g' 

Ausgabe:

a\[ecaron]\nb\nc\n\[rcaron]d

Der Grund dafür, dass es kein Finale hat \n(im obigen Beispiel), besteht darin, dass im Musterbereich für die letzte Zeile einfach kein abschließendes Zeilenumbruchzeichen vorhanden sein wird (es Nwerden nur solche von vorherigen Zeilenenden, via , vorhanden sein)... sedgibt anschließend beim Beenden das abschließende Zeilenumbruchzeichen aus, aber selbst dann wird es xx=$(command substitution)entweder von $( )oder von backticks... aufgefressen.

Um ein letztes einzuschließen \n, ist nur eine letzte Ersetzung erforderlich.

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

Oder liegt es daran, dass Sie nicht einmal die Zwischenstimme erhalten \n?


Nur eine Randbemerkung: Sie müssen nicht zigsedsso viele Prozesse aufrufen. Sie können sie ;z. B. über (Doppelpunkt) verketten sed 's/ě/\\\[ecaron]/g; s/š/\\\[scaron]/g; .... oder die Doppelpunkte weglassen und einfach jeden Substitutionsausdruck in eine neue Zeile setzen, wodurch sie sich gut aneinanderreihen lassen ...

verwandte Informationen