$ echo {a..z}
这一行命令用到了括号展开(Brace expansion)功能,它可以用于生成任意的字符串。{x..y}是一个序列表达式,其中 x 和 y 都是单个字符,这个表达式展开后包含 x 与 y 之间的所有字符。
运行上面的命令会生成从 a 到 z 的所有字母:
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
$ printf"%c"{a..z}
在这一行命令中,printf 的格式为"%c",代表一个字符(character),后面的参数是从 a 到 z 的字符列表,字符之间以空格分隔。所以,当printf执行时,它依次输出每个字符直到所有字符全被处理完成为止。
下面是执行的结果:
abcdefghijklmnopqrstuvwxyz
$ printf "%c" {a..z} $'\n'
echo $(printf "%c" {a..z})
如果你想要每一行仅输出一个字母,在字符后面增加一个换行符:
$ printf "%c\n" {a..z}
如果想要快速地将 printf 的结果保存到变量中,可以使用-v选项:
printf -v alphabet "%c" {a..z}
结果会将abcdefghijklmnopqrstuvwxyz保存到变量alphabet中。
类似地,你也可以利用同样的语法生成一个数字列表,例如从1到100:
echo {1..100}
或者,如果你忘记这种方法,可以使用 seq 命令来做这个事情:
$ seq1 100
$ printf"%02d "{0..9}
$ echo{00..09}
老版本不包含该特性。
echo{w,t,}h{e{n{,ce{,forth}},re{,in,fore,with{,al}}},ither,at}
这是一个滥用括号展开的例子,看看最终输出的结果是什么:
是不是很棒?
你可以通过括号展开生成一组单词或者符号的排列。例如:
echo{a,b,c}{1,2,3}
上面的命令会生成以下结果:a1 a2 a3 b1 b2 b3 c1 c2 c3。首先,它取出第一个括号中的第一个元素a,然后依次与第二个括号{1,2,3}的所有元素组合,生成a1 a2 a3,依此类推。
$ echo foo{,,,,,,,,,,}这一行命令两次利用了括号展开功能,字符串 foo 与10个空字符串组合,最终生成10分拷贝:
$ echo"$x$y"这一行命令简单地将两个变量的值连接在一起,所以如果x 变量的值为foo ,而y 的值为bar ,则结果为foobar 。
x=-n y=" foo" echo $x$y执行后的输出:
x=-n $ y=" foo" $echo "$x$y" -n foo不过,如果你要将两个字符串相连的结果赋值给变量,是可以将双引号省略的:
var=$x$y
$ IFS=- read-r x y z <<< "$str"这里我们使用read x 命令从标准输入读取内容,分割后并依次保存到x y z 变量中。其中,$x 为foo , $y 为 bar , $z 为 baz 。
$ IFS=- read-ra parts <<< "foo-bar-baz"在这里,-a 选项告诉read 命令将分割后的元素保存到数组parts 中。随后,你可以通过${parts[0]} , ${parts[1]} 和${parts[2]} 来访问数组的各个元素,或者通过${parts[@]} 来访问所有元素。
$ while IFS= read -rn1 c; do # do something with $c done <<< "$str"
$ echo${str/foo/bar}这一行命令用到了 参数展开 的另外一种形式:${var/find/replace} ,找到$var 变量中的find 字符串,并将它替换成bar 。
$ echo${str//foo/bar}
$ if [[ $file = *.zip ]]; then # do something fi
这一行命令是说,如果$file的值匹配*.zip,则执行if语句里的命令。这种语法下的模式是最简单的通配符(glob pattern)匹配,通配符包括* ? [...]。其中,*可以匹配一个或者多个字符,?只能匹配单个字符,[...]能够匹配任意出现在中括号里面的字符或者一类字符集。
下面是另外一个例子,用来判断回答是否匹配 Y 或者 y:er is Y or y:
$ if [[ $answer = [Yy]* ]]; then # do something fi
$ if [[ $str =~ [0-9]+\.[0-9]+ ]]; then # do something fi
$ echo${#str}这里我们又用到了参数展开(也可以叫参数替换)的语法: ${#str} ,它返回$str 变量值的长度。
$ str="hello world" $ echo ${str:6}
这一行命令通过子串提取操作,从字符串hello world中取到了子串world。子串提取操作的语法格式为${var:offset:length},它的意思是说从变量var中,提取第offset个位置(下标从0开始计算)开始的总共length个数的字符。在我们这个例子中,忽略了length,默认会返回所有剩余的字符。
下面是另外一个例子,返回$str变量中第7、8位置的两个字符:
$ echo${str:7:2}输出结果为or 。
$ declare -u var $ var="foo bar“
$ echo $var FOO BAR注意,-u 选项也是在 Bash 4 新版本中引入的功能,在低版本下是没有的。类似地,你还可以使用 Bash 4 提供的另外一种参数展开语法${str^^} ,也可以将字符串转换成太写的格式:
$ str="zoo raw" $ echo ${str^^}
$ declare -l var $ var="FOO BAR"
$ echo $var foo bar同样,只有 Bash 4 以及以上的版本才支持-l选项。另外一种方式是使用参数展开语法:
$ str="ZOO RAW"
$ echo ${str,,}我补充一句,如果是 Bash 4 以下,还是老老实实地用tr命令就可以了。