shell中的特殊字符【2】

shell中的特殊字符

* 星号

  • 作为匹配文件名扩展的一个通配符,能自动匹配给定目录下的每一个文件;
bash$ echo *
abs-book.sgml add-drive.sh agram.sh alias.sh
  • 正则表达式中可以作为字符限定符,表示其前面的匹配规则匹配任意次;

-算术运算中表示乘法。

** 双星号

  • 算术运算中表示求幂运算。

? 问号

  • 表示条件测试;

  • 在双括号内表示C风格的三元操作符

(( var0 = var1<98?9:21 ))
#                ^ ^

# if [ "$var1" -lt 98 ]
# then
#   var0=9
# else
#   var0=21
# fi
  • 参数替换表达式中用来测试一个变量是否设置了值;
#!/bin/bash

#  Check some of the system's environmental variables.
#  This is good preventative maintenance.
#  If, for example, $USER, the name of the person at the console, is not set,
#+ the machine will not recognize you.

: ${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?}
  echo
  echo "Name of the machine is $HOSTNAME."
  echo "You are $USER."
  echo "Your home directory is $HOME."
  echo "Your mail INBOX is located in $MAIL."
  echo
  echo "If you are reading this message,"
  echo "critical environmental variables have been set."
  echo
  echo
  • 作为通配符,用于匹配文件名扩展特性中,用于匹配单个字符;

  • 正则表达式中,表示匹配其前面规则0次或者1次。

$ 美元符号

  • 作为变量的前导符,用作变量替换,即引用一个变量的内容
var1=5
var2=23skidoo

echo $var1     # 5
echo $var2     # 23skidoo
  • 在正则表达式中被定义为行末(End of line)。

“${}”

  • 参数替换 ,基本作用和$一致,在链接字符串方面稍有差别
your_id=${USER}-on-${HOSTNAME}
echo "$your_id"
#
echo "Old \$PATH = $PATH"
PATH=${PATH}:/opt/bin  # Add /opt/bin to $PATH for duration of script.
echo "New \$PATH = $PATH"

$’…’

  • 引用展开
    执行单引号内的转义内容(单引号原本是原样引用的),这种方式会将引号内的一个或者多个[]转义后的八进制,十六进制值展开到ASCII或Unicode字符。
quote=$'\042'.

$*, $@

  • 位置参数,这个在使用脚本文件的时候,在传递参数的时候会用到,两者都能返回调用脚本文件的所有参数

  • $* 是将所有参数作为一个整体返回(字符串)

  • $@是将每个参数作为单元返回一个参数列表

index=1          # Initialize count.

echo "Listing args with \"\$*\":"
for arg in "$*"  # Doesn't work properly if "$*" isn't quoted.
do
  echo "Arg #$index = $arg"
  let "index+=1"
done             # $* sees all arguments as single word. 
echo "Entire arg list seen as single word."

echo

index=1          # Reset count.
                 # What happens if you forget to do this?

echo "Listing args with \"\$@\":"
for arg in "$@"
do
  echo "Arg #$index = $arg"
  let "index+=1"
done             # $@ sees arguments as separate words. 
echo "Arg list seen as separate words."

echo

index=1          # Reset count.

echo "Listing args with \$* (unquoted):"
for arg in $*
do
  echo "Arg #$index = $arg"
  let "index+=1"
done             # Unquoted $* sees arguments as separate words. 
echo "Arg list seen as separate words."

exit 0

代码输出:
$*和$@的区别

$?

  • 此变量值在使用的时候,返回的是最后一个命令、函数、或脚本的退出状态码值,如果没有错误则是0,如果为非0,则表示在此之前的最后一次执行有错误。 true 的返回码是0 false的返回码是非0

$$

  • 进程ID变量,这个变量保存了运行当前脚本的进程ID值。

() 括号

  • 命令组。
    因为是在子shell内运行,因此在括号外面是没有办法获取括号内变量的值,但反过来,命令组内是可以获取到外面的值,这点有点像局部变量和全局变量的关系,在实作中,如果碰到要cd到子目录操作,并在操作完成后要返回到当前目录的时候,可以考虑使用subshell来处理;
a=123
( a=321; )        

echo "a = $a"   # a = 123
# "a" within parentheses acts like a local variable.
  • 数组的初始化
Array=(element1 element2 element3)

{xxx,yyy,zzz,…}

  • 在命令中可以用这种扩展来扩展参数列表
    注意的一点是,这花括号扩展中不能有空格存在,如果确实有必要空格,则必须被转义或者使用引号来引用
echo \"{These,words,are,quoted}\"   # " prefix and suffix
# "These" "words" "are" "quoted"


cat {file1,file2,file3} > combined_file
# Concatenates the files file1, file2, and file3 into combined_file.

cp file22.{txt,backup}
# Copies "file22.txt" to "file22.backup

花括号实例

{a..z}

  • 列举字符
#!/bin/bash
echo {a..z} # a b c d e f g h i j k l m n o p q r s t u v w x y z
# Echoes characters between a and z.

echo {0..3} # 0 1 2 3
# Echoes characters between 0 and 3.

base64_charset=( {A..Z} {a..z} {0..9} + / = )
# Initializing an array, using extended brace expansion.
# From vladz's "base64.sh" example script.

{} 花括号

  • 代码块
    这个是匿名函数,但是又与函数不同,在代码块里面的变量在代码块后面仍能访问。注意:花括号内侧需要有空格与语句分隔。
#!/bin/bash
a=123
{ a=321; }
echo "a = $a"   # a = 321   (value inside code block)

# Thanks, S.C.
  • {} 代码块里的内容可以通过IO重定向
#!/bin/bash
# Reading lines in /etc/fstab.

File=/etc/fstab

{
read line1
read line2
} < $File

echo "First line in $File is:"
echo "$line1"
echo
echo "Second line in $File is:"
echo "$line2"

exit 0

# Now, how do you parse the separate fields of each line?
# Hint: use awk, or . . .
# . . . Hans-Joerg Diers suggests using the "set" Bash builtin.
  • 在xargs -i中的话,还可以作为文本的占位符,用以标记输出文本的位置。
#!/bin/bash
# copydir.sh

#  Copy (verbose) all files in current directory ($PWD)
#+ to directory specified on command-line.

E_NOARGS=85

if [ -z "$1" ]   # Exit if no argument given.
then
  echo "Usage: `basename $0` directory-to-copy-to"
  exit $E_NOARGS
fi  

ls . | xargs -i -t cp ./{} $1
#            ^^ ^^      ^^
#  -t is "verbose" (output command-line to stderr) option.
#  -i is "replace strings" option.
#  {} is a placeholder for output text.
#  This is similar to the use of a curly-bracket pair in "find."
#
#  List the files in current directory (ls .),
#+ pass the output of "ls" as arguments to "xargs" (-i -t options),
#+ then copy (cp) these arguments ({}) to new directory ($1).  
#
#  The net result is the exact equivalent of
#+   cp * $1
#+ unless any of the filenames has embedded "whitespace" characters.

exit 0

{} \;

  • 这个{}是表示路径名,现在接触到的情况看,好像只用在find命令里
find ~/ -name 'core*' -exec rm {} \;
# Removes all core dump files from user's home directory.

[ ] 中括号

  • 测试的表示 Shell会测试在[]内的表达式

  • 在数组的上下文中,表示数组元素,方括号内填上数组元素的位置就能获得对应位置的内容

Array[1]=xxx
echo ${Array[1]};
  • 表示字符集的范围,在正表达式中,方括号表示该位置可以匹配的字符集范围。
"[xyz]" matches any one of the characters x, y, or z.

"[c-n]" matches any one of the characters in the range c to n.

"[B-Pk-y]" matches any one of the characters in the ranges B to P and k to y.

"[a-z0-9]" matches any single lowercase letter or any digit.
Combined sequences of bracketed characters match common word patterns. "[Yy][Ee][Ss]" matches yes, Yes, YES, yEs, and so forth. "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" matches any Social Security number.

"[^b-d]" matches any character except those in the range b to d. This is an instance of ^ negating(否定) or inverting the meaning of the following RE (taking on a role similar to ! in a different context).

[[ ]]

  • 这个结构也是测试,测试[[]]之中的表达式(Shell的关键字)。这个比单中括号更能防止脚本里面的逻辑错误,比如:&&,||,<,>操作符能在一个[[]]里面测试通过,但是在[]却不能通过。[[]]里面没有文件名扩展(filename expansion)或是词分隔符(Word splitting),但是可以用参数扩展(Parameter expansion)和命令替换(command substitution)。不用文件名通配符和像空白这样的分隔符。注意,这里面如果出现了八进制,十六进制等,shell会自动执行转换比较。
# [[ Octal and hexadecimal evaluation ]]
# Thank you, Moritz Gronbach, for pointing this out.


decimal=15
octal=017   # = 15 (decimal)
hex=0x0f    # = 15 (decimal)

if [ "$decimal" -eq "$octal" ]
then
  echo "$decimal equals $octal"
else
  echo "$decimal is not equal to $octal"       # 15 is not equal to 017
fi      # Doesn't evaluate within [ single brackets ]!


if [[ "$decimal" -eq "$octal" ]]
then
  echo "$decimal equals $octal"                # 15 equals 017
else
  echo "$decimal is not equal to $octal"
fi      # Evaluates within [[ double brackets ]]!

if [[ "$decimal" -eq "$hex" ]]
then
  echo "$decimal equals $hex"                  # 15 equals 0x0f
else
  echo "$decimal is not equal to $hex"
fi      # [[ $hexadecimal ]] also evaluates!

$[ … ]

  • 在方括号里面执行整数表达式
a=3
b=7

echo $[$a+$b]   # 10
echo $[$a*$b]   # 21

(( ))

  • 功能和上面的 [] []是会返回里面表达式的值的,而(())只是执行,并不会返回值。两者执行后如果变量值发生变化,都会影响到后继代码的运行。可对变量赋值,可以对变量进行一目操作符操作,也可以是二目,三目操作符。
#!/bin/bash
# c-vars.sh
# Manipulating a variable, C-style, using the (( ... )) construct.

echo

(( a = 23 ))  #  Setting a value, C-style,
              #+ with spaces on both sides of the "=".
echo "a (initial value) = $a"   # 23

(( a++ ))     #  Post-increment 'a', C-style.
echo "a (after a++) = $a"       # 24

(( a-- ))     #  Post-decrement 'a', C-style.
echo "a (after a--) = $a"       # 23


(( ++a ))     #  Pre-increment 'a', C-style.
echo "a (after ++a) = $a"       # 24

(( --a ))     #  Pre-decrement 'a', C-style.
echo "a (after --a) = $a"       # 23

echo
echo

(( t = a<45?7:11 ))   # C-style trinary operator.
#       ^  ^ ^
echo "If a < 45, then t = 7, else t = 11."  # a = 23
echo "t = $t "                              # t = 7

echo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值