web-dev-qa-db-fra.com

Comment supprimer une nouvelle ligne d'une chaîne dans Bash

J'ai la variable suivante.

echo "|$COMMAND|"

qui retourne 

|
REBOOT|

Comment puis-je supprimer cette première nouvelle ligne?

82
Matt Leyland

Sous bash , il y a quelques bashismes:

La commande tr pourrait être remplacée par //bashism:

COMMAND=$'\nREBOOT\r   \n'
echo "|${COMMAND}|"
|
   OOT
|

echo "|${COMMAND//[$'\t\r\n']}|"
|REBOOT   |

echo "|${COMMAND//[$'\t\r\n ']}|"
|REBOOT|

Voir Expansion des paramètres et INDIQUANT dans la page de manuel de bash:

man -Pless\ +/\/pattern bash
man -Pless\ +/\\\'string\\\' bash

man -Pless\ +/^\\\ *Parameter\\\ Exp bash
man -Pless\ +/^\\\ *QUOTING bash

Plus loin...

Comme demandé par @AlexJordan, ceci supprimera les caractères spécifiés tous. Et si $COMMAND contient des espaces ...

COMMAND=$'         \n        RE BOOT      \r           \n'
echo "|$COMMAND|"
|
           BOOT      
|

CLEANED=${COMMAND//[$'\t\r\n']}
echo "|$CLEANED|"
|                 RE BOOT                 |

shopt -q extglob || { echo "Set Shell option 'extglob' on.";shopt -s extglob;}

CLEANED=${CLEANED%%*( )}
echo "|$CLEANED|"
|                 RE BOOT|

CLEANED=${CLEANED##*( )}
echo "|$CLEANED|"
|RE BOOT|

Prochainement:

COMMAND=$'         \n        RE BOOT      \r           \n'
CLEANED=${COMMAND//[$'\t\r\n']} && CLEANED=${CLEANED%%*( )}
echo "|${CLEANED##*( )}|"
|RE BOOT|

Remarque: bash doit activer l'option extglob (shopt -s extglob) pour pouvoir utiliser la syntaxe *(...).

85
F. Hauri
echo "|$COMMAND|"|tr '\n' ' '

remplacera la nouvelle ligne (dans POSIX/Unix, ce n'est pas un retour chariot) par un espace.

Pour être honnête, je penserais à passer de bash à quelque chose de plus sain. Ou éviter de générer ces données malformées en premier lieu.

Hmmm, il semble que cela pourrait aussi être un trou de sécurité horrible, selon la provenance des données.

67
Robin Green

Nettoyez votre variable en supprimant tous les retours chariot:

COMMAND=$(echo $COMMAND|tr -d '\n')
55
Maxime Chéramy

Utiliser bash:

echo "|${COMMAND/$'\n'}|"

(Notez que le caractère de contrôle de cette question est une "nouvelle ligne" (\n) et non un retour à la ligne (\r); ce dernier aurait pour résultat REBOOT| sur une seule ligne.)

Explication

Utilise l’extension de paramètre Bash Shell${parameter/pattern/string}:

Pattern est développé pour produire un modèle exactement comme dans l'extension de nom de fichier. Parameter est développé et la correspondance la plus longue de pattern par rapport à sa valeur est remplacée par string. [...] Si string est nul, les correspondances de pattern sont supprimées et les / suivants pattern peuvent être omis.

Utilise également la construction $''ANSI-C citant pour spécifier une nouvelle ligne sous la forme $'\n'. Utiliser une nouvelle ligne fonctionnerait aussi, bien que moins joli:

echo "|${COMMAND/
}|"

Exemple complet

#!/bin/bash
COMMAND="$'\n'REBOOT"
echo "|${COMMAND/$'\n'}|"
# Outputs |REBOOT|

Ou, en utilisant des nouvelles lignes:

#!/bin/bash
COMMAND="
REBOOT"
echo "|${COMMAND/
}|"
# Outputs |REBOOT|
4
wjordan

Vous pouvez simplement utiliser echo -n "|$COMMAND|".

2
Paulo

Si vous utilisez bash avec l'option extglob activée, vous pouvez supprimer uniquement les espaces finaux via:

shopt -s extglob
COMMAND=$'\nRE BOOT\r   \n'
echo "|${COMMAND%%*([$'\t\r\n '])}|"

Cela génère:

|
RE BOOT|

Ou remplacez %% par ## pour ne remplacer que les blancs.

1
zeroimpl

Ce qui a fonctionné pour moi était echo $testVar | tr "\n" " "

Où testVar contenait ma variable/script-output

0
Prachi

Ajout de answer pour montrer un exemple de suppression de plusieurs caractères, y compris\r en utilisant tr et en utilisant sed . Et illustrant en utilisant hexdump.

Dans mon cas, j’avais constaté qu’une commande se terminant par awk print du dernier élément |awk '{print $2}' de la ligne comprenait un retour chariot ainsi que des guillemets.

J'ai utilisé sed 's/["\n\r]//g' pour effacer le retour-chariot et les guillemets.

J'aurais aussi pu utiliser tr -d '"\r\n'.

Il est intéressant de noter que sed -z est nécessaire si vous souhaitez supprimer les caractères de saut de ligne.

$ COMMAND=$'\n"REBOOT"\r   \n'

$ echo "$COMMAND" |hexdump -C
00000000  0a 22 52 45 42 4f 4f 54  22 0d 20 20 20 0a 0a     |."REBOOT".   ..|

$ echo "$COMMAND" |tr -d '"\r\n' |hexdump -C
00000000  52 45 42 4f 4f 54 20 20  20                       |REBOOT   |

$ echo "$COMMAND" |sed 's/["\n\r]//g' |hexdump -C
00000000  0a 52 45 42 4f 4f 54 20  20 20 0a 0a              |.REBOOT   ..|

$ echo "$COMMAND" |sed -z 's/["\n\r]//g' |hexdump -C
00000000  52 45 42 4f 4f 54 20 20  20                       |REBOOT   |

Et cela est pertinent: Que sont le retour chariot, le saut de ligne et le saut de page?

  • CR ==\r == 0x0d
  • LF ==\n == 0x0a
0
gaoithe