2025-02-17

Bash字符串處理(與Java對照) – 2.字符串的表示方式(字符串常量)

In Java
你懂的!
使用單引號表示字符常量:'c'
使用雙引號表示字符串常量:"hello world"
 
Java字符轉義
\u???? 四位十進制Unicode字符
\??? 三位八進制字符
\n 換行(\u000a)(Insert a newline in the text at this point.)
\t 水平制表符(\u0009)(Insert a tab in the text at this point.)
\b 退格(\u0008)(Insert a backspace in the text at this point.)
\r 回車(\u000d)(Insert a carriage return in the text at this point.)
\f 換頁(\u000c)(Insert a formfeed in the text at this point.)
\' 單引號(\u0027)(Insert a single quote character in the text at this point.)
\" 雙引號(\u0022)(Insert a double quote character in the text at this point.)
\\ 反斜杠(\u005c)(Insert a backslash character in the text at this point.)
 
註:網上有很多資料都不一定正確,還是看Oracle網站上關於Characters的內容為好:
http://download.oracle.com/javase/tutorial/java/data/characters.html
 
In Bash
字符串的用途
在Bash中無處不是字符串,它可以
(1)作為命令;
(2)作為命令行參數;
(3)作為變量的值;
(4)作為重定向的文件名稱;
(5)作為輸入字符串(here string, here document);
(6)作為命令行的輸出。
 
字符串表示方式概述
在Bash中,字符串常量有多種表示方式
(1)不使用任何引號,比如 hello
(2)使用一對單引號括起來,比如 'hello'
(3)使用一對雙引號括起來,比如 "hello"
(4)使用美元符加上一對單引號括起來,比如 $'hello'
如果字符串中不包含特殊字符,那麼上述幾種表示方式是等效的。
 
友情提示:字符串的這幾種表示方式可以任意組合,比如 h'e'"l"$'lo' 與 hello是等效的。
 
[root@jfht ~]# echo hello
hello
[root@jfht ~]# echo 'hello'
hello
[root@jfht ~]# echo "hello"
hello
[root@jfht ~]# echo $'hello'
hello
[root@jfht ~]# echo h'e'"l"$'lo'
hello
[root@jfht ~]#
 
關於字符串表示的問題
在進一步對字符串的表示方式瞭解之前,請先回答下面的問題:
問題1:字符串中包含空格,應該怎麼表示?
問題2:字符串中包含制表符,應該怎麼表示?
問題3:字符串中包含單引號,應該怎麼表示?
問題4:字符串中包含雙引號,應該怎麼表示?
問題5:字符串中包含$,應該怎麼表示?
問題6:字符串中包含#,應該怎麼表示?
問題7:字符串中包含換行,即有多行,應該怎麼表示?
問題8:字符串中包含反斜杠,應該怎麼表示?
問題9:字符串中包含感嘆號,應該怎麼表示?
 
無引號(one of quoting  mechanisms:  the  escape  character)
在沒有用引號括起來時,所有的特殊字符都會產生特殊的作用,如果想讓它們失去特殊作用,就需要用轉義符(\)進行轉義。
man bash 寫道
A non-quoted backslash (\) is the escape character. It preserves the
literal value of the next character that follows, with the exception of
<newline>. If a \<newline> pair appears, and the backslash is not
itself quoted, the \<newline> is treated as a line continuation (that
is, it is removed from the input stream and effectively ignored).
 
空格是用來分隔命令與參數、參數與參數、變量賦值和命令的,所以如果字符串中有空格時,需要對空格進行轉義。
[root@jfht ~]# STR=hello world
-bash: world: command not found
[root@jfht ~]# STR=hello\ world
 
換行符是命令行之間的分隔符的一種(另外一種是分號),如果字符串比較長,就可以對換行符進行轉義,變成續行。
[root@jfht ~]# STR=hello\
> world
[root@jfht ~]#
 
在沒有任何引號括起來時,\跟上字符,那麼所跟的字符將失去特殊含義。比如 管道線(|)。
[root@jfht ~]# STR=hello|world
-bash: world: command not found
[root@jfht ~]# STR=hello\|world
[root@jfht ~]#
 
單引號(single quote,full quoting)
Advanced Bash-Scripting Guide: Chapter 3. Special Characters 寫道
full quoting [single quote]. 'STRING' preserves all special characters within STRING. This is a stronger form of quoting than "STRING".
 
在單引號中,所有的特殊字符豆漿失去其特殊含義。這樣也就導致在單引號中無法表示單引號字符本身。
man bash QUOTING 寫道
Enclosing characters in single quotes preserves the literal value of
each character within the quotes. A single quote may not occur between
single quotes, even when preceded by a backslash.
 
 
[root@jfht ~]# echo '$'
$
[root@jfht ~]# echo '`'
`
[root@jfht ~]# echo '\'
\
[root@jfht ~]# echo '!'
!
[root@jfht ~]# echo 'begin of string
> some strings
> end of string'
begin of string
some strings
end of string
[root@jfht ~]#
 
下面展示一下單引號表示的字符串在腳本中的表現。
 
Bash腳本:test_single_quote.sh
Bash代碼 
#!/bin/sh 
 
echo '$' 
 
echo '`' 
 
echo '\' 
 
echo '!' 
 
echo 'start of string 
some strings 
end of string' 
 
[root@jfht ~]# chmod +x ./test_single_quote.sh
[root@jfht ~]# ./test_single_quote.sh
$
`
\
!
start of string
some strings
end of string
[root@jfht ~]#
 
雙引號(double quote,partial quoting)
Advanced Bash-Scripting Guide: Chapter 3. Special Characters 寫道
partial quoting [double quote]. "STRING" preserves (from interpretation) most of the special characters within STRING.
在雙引號中,大部分特殊字符失去瞭其特殊含義,比如 註釋(#)、命令分隔符(;)、管道線(|)、通配符(?*)等。
 
[root@jfht work191]# echo *
cgen ct08 hycu2 hyfc2 jlib keyc mdbc msgc sms web_spider xqt_admin xqt_demo xqt_server zjlt_mhr_files zjlt_mhr_server zjlt_mhr_user zjlt_mhr_web
[root@jfht work191]# echo "*"
*
[root@jfht work191]# echo #

[root@jfht work191]# echo "#"
#
[root@jfht work191]#
 
Advanced Bash-Scripting Guide: Chapter 5. Quoting 寫道
This prevents reinterpretation of all special characters within the quoted string — except $, ` (backquote), and \ (escape). Keeping $ as a special character within double quotes permits referencing a quoted variable ("$variable"), that is, replacing the variable with its value
man bash 寫道
Enclosing characters in double quotes preserves the literal value of
all characters within the quotes, with the exception of $, `, and \.
 
在雙引號中,特殊字符包括:美元符($)、反引號(`)、轉義符(\)、感嘆號(!),其他的特殊字符就不用管瞭。(為啥在此處寫上“感嘆號(!)”呢,請看後文分解)
 
man bash 寫道
The characters $ and ` retain their special meaning within double
quotes.
 
在雙引號中,美元符($)可以引用變量,將被替換為變量的值,比如
"$VAR"   被替換為變量VAR的值,但"$VAR123"將被替換為變量VAR123的值,所以最好用大括號把變量括起來,避免意想不到的錯誤出現;
"${VAR}"   被替換為變量VAR的值,"${VAR}123"將被替換為變量VAR的值再跟上123;
"${VAR:-DEFAULT}"  當變量VAR沒有定義或者為空時,替換為DEFAULT,否則替換為變量VAR的值;
"$(command line)"  相當於 "`command line`",將被替換為命令行執行的標準輸出信息
 
變量VAR沒有定義。
[root@jfht ~]# echo "$VAR"

[root@jfht ~]# echo "${VAR}"
 
[root@jfht ~]# echo "$VAR123"

[root@jfht ~]# echo "${VAR}123"
123
[root@jfht ~]# echo "${VAR:-DEFAULT}"
DEFAULT
現在定義VAR變量。
[root@jfht ~]# VAR="Hello World"
[root@jfht ~]# echo "$VAR"
Hello World
[root@jfht ~]# echo "${VAR}"
Hello World
[root@jfht ~]# echo "$VAR123"

[root@jfht ~]# echo "${VAR}123"
Hello World123
[root@jfht ~]# echo "${VAR:-DEFAULT}"
Hello World
現在測試一下命令執行輸出結果。
[root@jfht ~]# echo "$(pwd)"
/root
[root@jfht ~]#
 
在雙引號中,反引號(`)將被替換為命令行執行的標準輸出信息
"`ls`" 相當於 "$(ls)",將被替換為ls命令的執行結果,即列出當前目錄的文件名;
"`date +%F`"相當於"$(date +%F)",將被替換為date +%F的執行結果,即當天的日期,比如2011-09-01
 
[root@jfht ~]# echo "`pwd`"
/root
[root@jfht ~]# echo "`date +%F`"
2011-09-02
[root@jfht ~]# echo "$(date +%F)"
2011-09-02
[root@jfht ~]#
 
man bash 寫道
The backslash retains its special meaning only when followed
by one of the following characters: $, `, ", \, or <newline>. A double
quote may be quoted within double quotes by preceding it with a back-
slash.
 
在雙引號中,轉義符(\)是為瞭方便創建包含特殊字符的字符串,特殊字符的前面需要加上\進行轉義
\"  雙引號 gives the quote its literal meaning
\$  美元符 gives the dollar sign its literal meaning (variable name following \$ will not be referenced)
\\  反斜杠、轉義符本身 gives the backslash its literal meaning
\` 反引號
\<newline> 就是\跟上換行,那麼換行的作用不再有,隻起到續行的作用。
 
[root@jfht ~]# echo ""

[root@jfht ~]# echo "hello
> world"
hello
world
[root@jfht ~]#
[root@jfht ~]# echo "hello world\""
hello world"
[root@jfht ~]# echo "hello world\$" 
hello world$
[root@jfht ~]# echo "hello world\\"
hello world\
[root@jfht ~]# echo "hello world\`"
hello world`
[root@jfht ~]# echo "hello world\
> yes"
hello worldyes
[root@jfht ~]#
 
在雙引號中,感嘆號(!)的含義根據使用的場合有所不同,在命令行環境,它將被解釋為一個歷史命令,而在腳本中,則不會有特殊含義。
Advanced Bash-Scripting Guide: 5.1. Quoting Variables 寫道
Encapsulating "!" within double quotes gives an error when used from the command line. This is interpreted as a history command. Within a script, though, this problem does not occur, since the Bash history mechanism is disabled then.
 
在命令行環境,感嘆號(!)稱之為“歷史擴展字符(the  history  expansion character)”。
[root@jfht ~]# pwd
/root
[root@jfht ~]# echo "!"
-bash: !: event not found
[root@jfht ~]# echo "!pwd"
echo "pwd"
pwd
[root@jfht ~]#
 
在腳本中使用感嘆號,將不會進行歷史擴展。
 
Bash腳本:test_exclamation_mark.sh
Bash代碼 
#!/bin/sh 
 
echo "!" 
 
pwd 
echo "!pwd" 
 
[root@smsgw root]# ./test_exclamation_mark.sh
!
/root
!pwd
[root@smsgw root]#
 
 
$' … '(ANSI-C Quoting)
前面講到,包圍在單引號之內的字符都不會有特殊含義,所以單引號本身並不能在一對單引號中出現。但是在前面加上$之後,就可以使用\進行轉義瞭,\的轉義含義與C語言中的相同。
Advanced Bash-Scripting Guide: Chapter 3. Special Characters 寫道
$' … '
    Quoted string expansion. This construct expands single or multiple escaped octal or hex values into ASCII or Unicode characters.
 
Advanced Bash-Scripting Guide: 5.2. Escaping 寫道
The $' … ' quoted string-expansion construct is a mechanism that uses escaped octal or hex values to assign ASCII characters to variables, e.g., quote=$'\042'.
 
man bash 寫道
Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped charac-
ters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as fol-
lows:
\a alert (bell)
\b backspace
\e an escape character (not ANSI C)
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote
\nnn the eight-bit character whose value is the octal value nnn (one to three digits)
\xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
\cx a control-x character

The expanded result is single-quoted, as if the dollar sign had not been present.
 
叮當一聲。
[root@jfht ~]# echo $'\a'
 
叮當三聲。
[root@jfht ~]# echo $'\a\a\a'
 
單引號。
[root@jfht ~]# echo $'\''
'
八進制表示的ASCII字符。
[root@jfht ~]# echo $'\101\102\103\010'
ABC
[root@jfht ~]#
[root@jfht ~]#

$"…"(Locale-Specific Translation)
在雙引號之前加上$,這部分內容還未能很好的理解,就不說瞭。望高人指點一二。
man bash 寫道
A double-quoted string preceded by a dollar sign ($) will cause the
string to be translated according to the current locale. If the cur-
rent locale is C or POSIX, the dollar sign is ignored. If the string
is translated and replaced, the replacement is double-quoted.

作者“Bash @ Linux”
 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *