1. 程式人生 > 其它 >全網最詳細的echo -ne 命令效果演示

全網最詳細的echo -ne 命令效果演示

echo -e-e 表示 enable interpretation of backslash escapes,即啟用反斜槓\轉義。
若字串中出現以下字元,則特別加以處理,而不會將它當成一般文字輸出:

字元 含義
\a 發出警告聲;
\b 退格(backspace):
游標向前移動一個字元;
\c produce no further output:
這條echo命令中 \c 後面的部分都不打印出來,
包括製表符,換行符,換頁符都不列印,
游標也保持在當前位置不移動。
\f form feed
換行,但是游標位置保持在下一行的當前列;
\n 換行,並且游標移至行首;
\r 回車(carriage return): 將游標位置移到本行開頭
(但是,如果想要不換行,應該使用 echo -ne "xxx\r");
\t horizontal tab;
\v vertical tab;游標豎直向下移動一行。類似按 ↓ 時的效果。
換言之,游標換行,但是保持在當前列;
效果類似 \f
\ 插入\字元;
\0NNN 插入 NNN(八進位制)所代表的ASCII字元;
\xHH 插入HH(十六進位制)所代表的ASCII字元;

\b

首先來測試一下 \b 的效果

#!/bin/bash

var=abc

echo $var
echo "$var\b"
echo -e "$var\b"
echo -e "$var\bd"
echo $var\b
echo -e $var\b
echo -e $var\\bd

列印結果如下:

abc
abc\b
abc
abd
abcb
abcb
abd
命令 列印結果 分析
echo $var abc (不做分析)
echo "$var\b" abc\b 沒有加轉義引數 -e,所以\b原樣輸出
echo -e "$var\b" abc 因為\b後面沒有字元,所以 abc 還是 abc
echo -e "$var\bd" abd 游標位置從原字元 c 的後面移到了 c 的前面,
因此新輸入的字元 d 即覆蓋了字元 c。
這也就是網上都說 \b 可以刪除一個字元的原因
echo $var\b
echo -e $var\b
abcd \
被忽略了
echo -e $var\\bd abd 這個例子說明
不用雙引號包裹字串也可以,
但是要用 \\b 來表示 \b

\c

接下來測試一下 \c 的效果


#!/bin/bash

echo "line 1"
echo "line 2"
echo -e "line 3\c"
echo "line 4"

列印結果如下:

[admin@centOS-01 ~]$ sh c.sh
line 1
line 2
line 3line 4
[admin@centOS-01 ~]$

我們發現兩條 echo "line 1" 執行完,游標會自動換行且移動至行首位置。因此, echo "line 2" 會從第二行開始列印。
但是,當我們執行 echo -e "line 3\c" 時,就不會自動加上換行符號,游標也停留在當前位置(我猜c即current),那麼 echo "line 4" 就會緊跟著字元 3 之後輸出。
另外,不加雙引號的寫法如下:

echo -e line 3\\c

再來看一個例子,當 \c 不在字串末尾時,末尾也不會加上換行符

#!/bin/bash
echo -e "a\c bcdefg"

輸出結果為

[admin@centOS-01 ~]$ sh c.sh
a[admin@centOS-01 ~]$ 

我驚奇地發現 bcdefg 全都沒有打印出來。
而且因為沒有換行符的緣故。a[admin@centOS-01 ~]$ 同一行顯示了。
如果,如果是和 \c 不在同一條命令中字串可以正常列印:

#!/bin/bash
echo -e "a\c\n"
echo bc

列印結果為

[admin@centOS-01 ~]$ sh c.sh
abc
[admin@centOS-01 ~]$

echo -e "a\c\n" 只打印出一個 a 字元,且游標就停留在 a 之後。
所以,在 \c 之後出現的,不管是 \n 還是 \t 都不會打印出來。
相反地,另一條命令 echo bc 還是正常在 a 之後打印出來了,並沒有受到上一條命令的影響。

\f

如果使用 echo -e "\f" 效果並不好,因此我們使用 echo -ne "\f" 來測試。
-n 引數作用是 do not output the trailing new line,就是不自動在末尾加上換行符。
測試指令碼如下:

#!/bin/bash

echo -ne "\f1"
echo -ne "2\f2"
echo -ne "333\f"
echo "444"

輸出結果如下:


12
  2333
      444

當把 \f 放在行首時,就效果就等同於 \n。因此,echo -ne "\f1"echo -ne "\n1" 效果是一樣的。
\f 放在非行首位置,它會有 \n 的效果,而且會讓游標移動到與當前位置相同的列。
這是由於這個特性,我覺得 \f 適合“階梯式”列印,例如以下這段程式碼

#!/bin/bash

for i in 1 2 3 4 5
do
  echo -ne $i\\f
done

輸出效果如下:

1
 2
  3
   4
    5

\r

\r (回車,Carriage Return)也是我覺得很有意思的一個引數,放在行尾時,可以用於“重新整理(但又不完全重新整理)當前行的文字”。
但是,最好也是使用 echo -ne "\r" ,才能發揮它的作用。
另外,不加命令 sleep 1 看不到任何輸出結果...

#!/bin/bash

for i in 1 2 3 4 5
do
  echo -ne "Line $i\r"
  sleep 1
done

效果如下圖所示:

需要注意的是,入股後輸出的內容比先輸出的長,會出現奇怪的列印結果:

#!/bin/bash

echo -ne "Hello World\r"
sleep 1
echo -ne "Xxx Zzz\r" 
sleep 1

列印結果如下:

因為先列印的字串 Hello WorldXxx Zzz 長,所以 echo -ne "Xxx Zzz\r" 顯示的結果是 Xxx Zzzorld,這樣詭異的結果。
因此,大家在實際編寫 shell 指令碼時要避免這種情況。

\t 和 \v

我們還是先看一段程式碼:

#!/bin/bash

echo -e "a\tb\tc\td"

echo -e "1\v2\v3"

列印結果如下:

a	b	c	d
1
 2
  3

網上也有人說 \v\f 相同,執行下面一段指令碼:

#!/bin/bash

echo -ne "1\f"
echo -e "2\f"
echo -ne "1\v"
echo -e "2\v"

列印結果為

1
 2

1
 2

此時,\v\f 居然產生了相同的效果。
按理說 \f 作為換頁符,應該會將整個終端螢幕清空空,然後再輸出內容。但是,並沒有出現這個效果,感覺就像是削弱得和 \v 一樣了。

\0NNN 和 \xHH

[geekziyu@centOS-01 ~]$ echo -e "\0101"
A
[geekziyu@centOS-01 ~]$ echo -e "\x61"
a

\0101 表示將八進位制數 101(即十進位制 65)轉義為對應 ASCII 字元程式碼表中的字元 A;
\x61 表示將十六進位制數 61(即十進位制 97)轉義為對應 ASCII 字元程式碼表中的字元 a;

\n

#!/bin/bash

echo "1\n"
echo -e "2\n"
echo "3"

列印結果:

[admin@centOS-01 ~]$ sh next.sh
1\n
2

3
[admin@centOS-01 ~]$

換行符大家都應該很熟悉了,但是不要忘記加上 -e 引數。
如果沒有用 -ne 而只是用了 -e,那麼你就會發現 2 和 3 之間多出一個空行。