Comment supprimer une ligne avec echo?

60

Je sais que je pourrais supprimer les trois derniers caractères avec:

echo -ne '\b\b\b'

Mais comment puis-je supprimer une ligne complète? Je veux dire que je ne veux pas utiliser:

echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'

... etc ... pour supprimer une longue ligne.

LanceBaynes
la source
2
Pour ceux qui souhaitent écrire en continu sur la même ligne echo -ne "\033[2K" ; printf "\r":, la ligne est comme neuve, comme si elle n’avait jamais été écrite auparavant.
Bonjour le monde
2
Je suis sûr que vous pouvez simplement utiliser echo -ne "\e[2K\r". Mais ANSI échappe à FTW, néanmoins.
Parthian Shot

Réponses:

57

Vous pouvez utiliser \bou \rpour déplacer le curseur en arrière puis écraser le caractère imprimé avec un nouveau caractère. Notez que ni \bni \rsupprime les caractères imprimés. Cela déplace simplement le curseur en arrière. \brecule le curseur d'un caractère et le \rdéplace au début de la ligne.

Exemple: les deux

echo -e 'foooo\b\b\b\b\bbar'

et

echo -e 'foooo\rbar'

imprimera:

baroo

Si vous souhaitez supprimer les caractères, vous devez utiliser la solution de contournement suivante:

echo -e 'fooooo\r     \rbar'

sortie:

bar  

Extrait de man echo:

   If -e is in effect, the following sequences are recognized:

   \0NNN  the character whose ASCII code is NNN (octal)

   \\     backslash

   \a     alert (BEL)

   \b     backspace

   \c     produce no further output

   \f     form feed

   \n     new line

   \r     carriage return

   \t     horizontal tab

   \v     vertical tab

   NOTE: your shell may have its own version of echo, which usually super‐
   sedes the version described here.  Please refer to your  shell's  docu‐
   mentation for details about the options it supports.
lesmana
la source
4
Oui, mais echo -e 'fooooooooo\rbarfait écho à barooooooo.
Mat
1
Oui, tu as raison. Notez que les echo -e 'foooo\b\b\b\b\b\b\b\b\b\bbar'échos aussi baroo.
Lesmana
Si doux, fonctionne même parfaitement printf.
Michael-O
4
Réponse très imprécise. Celui de Kevin est vraiment meilleur
Mike Aski
88

Vous recherchez des évasions terminales . En particulier, pour effacer de la position du curseur au début de la ligne:

echo -e "\033[1K"

Ou tout ce qui est sur la ligne, quelle que soit la position du curseur:

echo -e "\033[2K"

Et vous pouvez faire toutes sortes d'autres astuces avec les évasions de terminal aussi.

Kevin
la source
6
Cela suppose un terminal ou un émulateur compatible VT100 (hypothèse plutôt sûre de nos jours).
Keith Thompson
2
Si vous voulez effacer quelque chose que vous venez de faire écho, votre écho précédent doit avoir le drapeau -n, ou vous serez envoyé sur une nouvelle ligne
djjeck
1
Si vous voulez écrire autre chose, sur la ligne que vous effacez, ajoutez un drapeau -n sur l'écho ci-dessus, sinon vous passerez à une nouvelle ligne juste après l'avoir effacé. Ajoutez également un \ r à la chaîne ci-dessus, sinon votre nouveau contenu n'ira pas au début de cette ligne.
djjeck
-1 | -ecomme echoargument n'est pas compatible POSIX + je n'aime pas les séquences d'échappement. Préférez printfou tput.
LinuxSecurityFreak le
@Vlastimil pourquoi voudriez-vous voter cela? OP n'a pas demandé de réponse à votre question. Peut-être aurait-il dû préciser ce -eparamètre pour qu'il echone soit pas conforme à POSIX mais quand même ...
jeudi
35

Si vous souhaitez effacer la ligne, je vous suggère d'utiliser une combinaison du retour de chariot mentionné par les personnes et de terminfo.

# terminfo clr_eol
ceol=$(tput el)
echo -ne "xyzzyxyzzy\r${ceol}foobar"

Cela va écrire xyzzyxyzzy, puis retourner au début de la ligne et envoyer la séquence "effacer jusqu'à la fin de la ligne" au terminal, puis écrire foobar. Le -nfait echo pas ajouter une nouvelle ligne après le foobar.

Arcege
la source
4
J'aime le genre de partie de cette solution spécifique qui protège de l'avenir - utiliser tput signifie peut-être que cela fonctionnera sur n'importe quel type de terminal.
Amos Shapira
2
Mieux que printf '%s\r%s%s' xyzzyxyzzy "$ceol" foobarpour la portabilité et d'éviter d' avoir le contenu de $ceolpasser par l' \xexpansion.
Stéphane Chazelas
Meilleure réponse si seulement parce que cela fonctionne avec des lignes arbitrairement longues. Merci!
Raphaël
travail parfait. Mais si je redimensionne l'écran du terminal plus petit que la ligne de sortie, il devient désordonné.
K.Sopheak le
11

Vous demandez explicitement echo, mais cette demande vous bloque. Voici une approche qui utilise la printfcommande intégrée de bash avec le développement d'accolade:

printf 'fooooooooo' # 10 characters
printf '\r'; printf ' %0.s' {0..9} # 10 expansions of the space character
kojiro
la source
1
parfait! exactement ce dont j'avais besoin
Omar S.
2
printf 'Statut: commencé'; sommeil 2s; printf '\ r'; printf 'Statut: mis à jour'; sommeil 2s; printf '\ r';
Omar S.
4

Voici un exemple utilisant les options sans retour à la ligne -n et retour chariot d' echo \r.

bash écrase la ligne terminale

#!/bin/bash

CHECK_MARK="\033[0;32m\xE2\x9C\x94\033[0m"

echo -e "\n\e[4mDoing Things\e[0m"
echo -n "doing thing 1..."
sleep 1
echo -e "\\r${CHECK_MARK} thing 1 done"
Derek Soike
la source
La coche fonctionne même sur RHEL6. Sympa pour des modifications purement esthétiques de mes scripts
oneindelijk
1

Au lieu de cela, echo -en "\r"vous pouvez également trouver la printf "\r"commande utile. De cette façon, vous pouvez formater la chaîne. par exemple:

for sec in {1..100}; do printf "\r %04d" ${sec}; sleep 0.1; done

Je le fais aussi généralement lorsque je travaille avec une analyse de fichier lente pour afficher le nom du fichier en cours de création sans créer de liste.

McPeppr
la source
-1 | Peut-être que vous vouliez intentionnellement faire un one-liner, mais ce n'est en fait que bon pour les tests. Je le réécrirais correctement avec de nouvelles lignes.
LinuxSecurityFreak le
0

Comme question est supprimer la ligne complète

J'ai utilisé la commande ci-dessous avec la combinaison de echoet sedsupprimer la ligne

Après exécution de la commande, le résultat sera vide. Puisque la ligne sera remplacée par aucune

commander

echo  "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" | sed -r "s/.*//g"
Praveen Kumar BS
la source
-1

Voici un exemple de compte à rebours que j'utilise:

i=10
while [ $i -gt 0 ]; 
do 
  printf "$i seconds remaining       " && printf '\r\033[1B'
  i=`expr $i - 1`
  sleep 1
  printf '\033[1A'
done
Mikiemorales
la source
-1 | Peut-être que vous vouliez intentionnellement faire un one-liner, mais ce n'est en fait que bon pour les tests. Je le réécrirais correctement avec de nouvelles lignes.
LinuxSecurityFreak le
Ensuite, allez-y et ajoutez une nouvelle réponse. Ou proposer une modification de ma réponse.
mikiemorales