J'ai la variable suivante.
echo "|$COMMAND|"
qui renvoie
|
REBOOT|
Comment puis-je supprimer ce premier saut de ligne ?
J'ai la variable suivante.
echo "|$COMMAND|"
qui renvoie
|
REBOOT|
Comment puis-je supprimer ce premier saut de ligne ?
La commande tr
pourrait être remplacée par le bashisme ${parameter/pattern/string}
:
COMMANDE=$'\nREBOOT\r \n'
echo "|${COMMANDE}|"
|
OOT
|
echo "|${COMMANDE//[$'\t\r\n']}|"
|REBOOT |
echo "|${COMMANDE//[$'\t\r\n ']}|"
|REBOOT|
Voir Extension de paramètre et QUOTING dans la page man de bash :
man -Pless\ +/parameter/pattern/string bash
man -Pless\ +/\/pattern bash
man -Pless\ +/\\\'string\\\' bash
man -Pless\ +/^\\\ *Parameter\\\ Exp bash
man -Pless\ +/^\\\ *QUOTING bash
${parameter//pattern/string} S'il y a deux barres obliques séparant le paramètre et le motif, toutes les correspondances du motif sont remplacées par la chaîne.
Comme demandé par @AlexJordan, ceci supprimera tous les caractères spécifiés. Alors que faire si $COMMANDE
contient des espaces...
COMMANDE=$' \n RE BOOT \r \n'
echo "|$COMMANDE|"
|
BOOT
|
read -r COMMANDE <<<"${COMMANDE//[$'\t\r\n']}"
echo "|$COMMANDE|"
|RE BOOT|
En répondant à la question de Vulwsztyn :
Pourquoi cela fonctionne-t-il lorsque le motif est vide ?
Dans ${COMMANDE//[$'\t\r\n ']}
:
/
signifie : Substitution de motifmotif
est /[$'\r\n ']
, commence par /
puis toutes les correspondances du motif sont remplacées par la chaînechaîne
est vide.tr
pour une seule chaîne !Comparons :
COMMANDE=$'\nREBOOT\r \n'
echo ${COMMANDE@Q}
$'\nREBOOT\r \n'
COMMANDE=$(echo $COMMANDE|tr -d '\n\t\r ')
echo ${COMMANDE@Q}
'REBOOT'
Ensuite
time for i in {1..1000};do
COMMANDE=$'\nREBOOT\r \n'
COMMANDE=$(echo $COMMANDE|tr -d '\n\t\r ')
done;echo ${COMMANDE@Q}
réel 0m2.785s
utilisateur 0m2.296s
système 0m0.774s
'REBOOT'
Avec
COMMANDE=$'\nREBOOT\r \n'
COMMANDE="${COMMANDE//[$'\t\r\n ']}"
echo ${COMMANDE@Q}
time for i in {1..1000};do
COMMANDE=$'\nREBOOT\r \n'
COMMANDE="${COMMANDE//[$'\t\r\n ']}"
done;echo ${COMMANDE@Q}
réel 0m0.006s
utilisateur 0m0.001s
système 0m0.004s
'REBOOT'
Effectuer 1'000 forks vers tr
prend plus de 2700ms sur mon hôte, alors que le même travail est effectué en 6ms ( 464.2x plus rapide !! ) en utilisant l'Extension de Paramètre intégrée de bash !!
echo "|$COMMAND|"|tr '\n' ' '
remplacera le saut de ligne (dans POSIX/Unix ce n'est pas un retour chariot) par un espace.
Pour être honnête, je penserais à passer à quelque chose de plus rationnel que bash. Ou éviter de générer ces données malformées en premier lieu.
Hmmm, cela semble également être une faille de sécurité horrible, en fonction de l'origine des données.
En utilisant bash
:
echo "|${COMMAND/$'\n'}|"
(Notez que le caractère de contrôle dans cette question est un 'saut de ligne' (\n
), et non un retour chariot (\r
); ce dernier aurait affiché REBOOT|
sur une seule ligne.)
Utilise l'expansion des paramètres de la coquille Bash (${parameter/pattern/string}):
Le pattern est développé pour produire un motif exactement comme dans le cas de l'expansion des noms de fichiers. Paramètre est développé et la correspondance la plus longue de pattern parmi sa valeur est remplacée par string. [...] Si string est nul, les correspondances de pattern sont supprimées et le / suivant pattern peut être omis.
Utilise également la construction de citation $''
ANSI-C pour spécifier un saut de ligne en tant que $'\n'
. Utiliser directement un saut de ligne fonctionnerait également, bien que moins élégant :
echo "|${COMMAND/
}|"
#!/bin/bash
COMMAND="$'\n'REBOOT"
echo "|${COMMAND/$'\n'}|"
# Résultat |REBOOT|
Ou, en utilisant des sauts de ligne :
#!/bin/bash
COMMAND="
REBOOT"
echo "|${COMMAND/
}|"
# Résultat |REBOOT|
Ajouter une réponse pour montrer un exemple de suppression de plusieurs caractères, y compris \r en utilisant tr et en utilisant sed. Et illustration en utilisant hexdump.
Dans mon cas, j'avais constaté qu'une commande se terminant par awk print du dernier élément |awk '{print $2}'
dans la ligne contenait un retour chariot \r ainsi que des guillemets.
J'ai utilisé sed 's/["\n\r]//g'
pour supprimer à la fois 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 l'on souhaite supprimer les caractères de saut de ligne \n.
$ COMMANDE=$'\n"REBOOT"\r \n'
$ echo "$COMMANDE" |hexdump -C
00000000 0a 22 52 45 42 4f 4f 54 22 0d 20 20 20 0a 0a |."REBOOT". ..|
$ echo "$COMMANDE" |tr -d '"\r\n' |hexdump -C
00000000 52 45 42 4f 4f 54 20 20 20 |REBOOT |
$ echo "$COMMANDE" |sed 's/["\n\r]//g' |hexdump -C
00000000 0a 52 45 42 4f 4f 54 20 20 20 0a 0a |.REBOOT ..|
$ echo "$COMMANDE" |sed -z 's/["\n\r]//g' |hexdump -C
00000000 52 45 42 4f 4f 54 20 20 20 |REBOOT |
Et ceci est pertinent: Quels sont le retour chariot, la saut de ligne et le saut de forme ?
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.