sed ne parvient pas à supprimer le caractère de nouvelle ligne

12

J'utilise seddepuis un certain temps, mais voici une bizarrerie que j'ai trouvée , que je ne suis pas en mesure de résoudre.

Permettez-moi d'expliquer mon problème avec le cas réel.


Scène 1

printf "ls" | xclip -selection clipboard
echo "ls" | xclip -selection clipboard

Dans la première commande, je dirige la printfsortie vers xclipafin qu'elle soit copiée dans le presse-papiers. Maintenant, printfcontrairement à echon'insère pas une nouvelle ligne à la fin par défaut. Donc, si je colle ce contenu dans le terminal, la lscommande copiée ne s'exécute pas automatiquement.

Dans le second, il y a une nouvelle ligne à la fin, donc coller le contenu du presse-papiers entraîne également l'exécution de la commande dans le presse-papiers.

C'est indésirable pour moi. Donc, je voulais supprimer la nouvelle ligne en utilisant sed, mais cela a échoué, comme expliqué dans la scène ci-dessous.

Scène # 2

echo "ls" | sed -r 's/\n//g' | xclip -selection clipboard

Le contenu du presse-papiers contient toujours une nouvelle ligne. Lorsque je le colle dans le terminal, la commande s'exécute automatiquement.

J'ai également essayé de supprimer le caractère de retour chariot \r. Mais nada. Il semble que je manque quelque chose de très crucial / fondamental ici.

shivams
la source

Réponses:

16

seddélimitations sur les \nlignes électroniques - elles sont toujours supprimées en entrée et réinsérées en sortie. Il n'y a jamais un \ncaractère ewline dans un sedespace de motif qui n'a pas eu lieu à la suite d'une modification que vous avez fait. Note: à l'exception de GNU sedde -zmode ...

Utilisez simplement tr:

echo ls | tr -d \\n | xclip -selection clipboard

Ou, mieux encore, oubliez sedcomplètement:

printf ls | xclip -selection clipboard
mikeserv
la source
Cela supprimera toutes les nouvelles lignes, souvent non souhaitables dans le generate-text | xclipcas. Cette réponse supprime uniquement la dernière nouvelle ligne.
Tom Hale
7

De nombreux outils de traitement de texte, y compris sed, fonctionnent sur le contenu de la ligne, à l'exception du caractère de nouvelle ligne. La première chose que sed fait lors du traitement d'une ligne est de supprimer la nouvelle ligne à la fin, puis il exécute les commandes dans le script et ajoute une nouvelle ligne finale lors de l'impression. Vous ne pourrez donc pas supprimer la nouvelle ligne avec sed.

Pour supprimer toutes les nouvelles lignes, vous pouvez utiliser à la trplace:

echo "ls" | tr -d '\n' | xclip

Gilles 'SO- arrête d'être méchant'
la source
4

Vous pouvez remplacer les sauts de ligne dans sed en lui passant l' option -z .

sed -z 's/\n/ /g'

Page de manuel Sed:

-z, --null-data lignes séparées par des caractères NUL

JSON C11
la source
Cela supprimera toutes les nouvelles lignes, ce qui n'est généralement pas souhaité dans le | xclipcas.
Tom Hale
2

Si vous placez simplement des commandes dans le presse-papiers

echo -n "ls " | xclip -selection clipboard

Si vous devez également effectuer des transformations plus complexes,

echo "ls  " | perl -pe 's/\n//' | xclip -selection clipboard
JJoao
la source
Hmm. Solution lisse. Je suppose qu'il est peut-être temps de passer à perl ou python pour regex.
shivams
3
@shivams - perlet pythonsont tous deux beaucoup plus lents que ceux qui sedpeuvent être utilisés correctement. Cependant, apprendre à l'utiliser correctement est la clé.
mikeserv
@mikeserv - je suis d'accord; spécial pour oneliner sed est merveilleux. Si les transformations vont devenir plus complexes, alors je préfère perl / python / gawk.
JJoao
1
@JJoa: Votre préférence est la vôtre, mais elle sedpeut faire bien plus que gérer uniquement vos monolignes, et elle peut probablement le faire plus rapidement que n'importe lequel des autres outils que vous mentionnez.
mikeserv
1
@mikeserv - encore une fois, je suis d'accord avec vous. Il y a un an, j'avais un système de traduction EN-PT écrit en sed (20000 s /.../.../), généré par sed! Et ça a marché! Plus tard, il est devenu Perl, pour avoir des tableaux, des hachages, des fonctions, des packages et CPAN.
JJoao
1

Pour supprimer uniquement la dernière nouvelle ligne , passez par:

sed -z '$ s/\n$//'

sedn'ajoutera pas de a \0à la fin du flux si le délimiteur est défini sur NULvia -z, alors que pour créer un fichier texte POSIX (défini pour se terminer par a \n), il affichera toujours une finale \nsans -z.

Par exemple:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender

Et pour prouver non NULajouté:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72                        foo.bar

Pour supprimer plusieurs sauts de ligne de fin , passez par:

sed -Ez '$ s/\n+$//'
Tom Hale
la source