根据之前学习zsh shell及oh my zsh的安装,学习一下网友提供的文章。
这里也作了一些zsh讲解
内容较多,全是好货,静下心来慢慢看,需要的时候再来查即可。
一、提示符
编辑用户目录下.zshrc文件,添加 export PS1=“my zsh ps1> "
下面是一些常用的转义变量
%T 系统时间时分
%* 系统时间时分秒
%D 系统时间年月日
%@ am/pm 时间
%n 登陆用户名
%B - %b 粗体打印
%U - %u 下划线打印
%S - %s 突出打印
%F - %f 前景色
%K - %k 背景色
%d 当前目录
%M 主机名
%m 截断过的主机名
%l 当前tty
%! 历史记录编号
$# 显示#号或>号
颜色
在 .zshrc 中 PROMPT= 前面添加 autoload -U colors && colors 来启用彩色提示符。
通常你需要将这些配置放在 %{ […] %} 里面确保光标不移动。
$fg[color] 会设置文本的颜色
命令 | 描述 |
---|---|
%F{color} […] %f | 和前面介绍的 $fg 是一样的,但是更简洁。还可以在 F 前面添加数字。 |
$fg_no_bold[color] | 设置文本为非粗体同时设定文本颜色 |
$fg_bold[color] | 设置文本为粗体同时设定文本颜色 |
$reset_color | 重置文本颜色(改为默认颜色)。不会重置粗体设定。使用 %b 来重置粗体设定。可以使用 %f 来简化配置。 |
%K{color} […] %k | 设置背景颜色。和非粗体文本颜色一样。任何单一数字前缀会设置背景为黑色。 |
PROMPT="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m %{$fg[yellow]%}%1~ %{$reset_color%}%#"
RPROMPT="[%{$fg[yellow]%}%?%{$reset_color%}]"
目录栈
可用于目录的快速跳转,在.zshrc中添加
DIRSTACKFILE="$HOME/.cache/zsh/dirs"
if [[ -f $DIRSTACKFILE ]] && [[ $#dirstack -eq 0 ]]; then
dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
[[ -d $dirstack[1] ]] && cd $dirstack[1]
fi
chpwd() {
print -l $PWD ${(u)dirstack} >$DIRSTACKFILE
}
DIRSTACKSIZE=20
setopt autopushd pushdsilent pushdtohome
## Remove duplicate entries
setopt pushdignoredups
## This reverts the +/- operators.
setopt pushdminus
帮助
autoload -U run-help
alias help=run-help
二、变量和语句
zsh 有 5 种变量:整数、浮点数(bash 不支持)、字符串、数组、哈希表(或者叫关联数组或者字典,本系列文章统一使用哈希表)
变量定义
Zsh 的变量多数情况不需要提前声明或者指定类型,可以直接赋值和使用(但哈希表是一个例外)。
# 等号两端不能有空格
num1=123
num2=123.456
str1=abcde
# 如果字符串中包含空格等特殊字符,需要加引号
str2='abc def'
# 也可以用双引号,但和单引号有区别,比如双引号里可以使用变量,而单引号不可以
str3="abc def $num1"
# 在字符串中可以使用转移字符,单双引号通用
str4="abc\tdef\ng"
# 输出变量,也可以使用 print
echo $str1
# 简单的数值计算
num3=$(($num1 + $num2))
# (( 中的变量名可以不用 $
% num3=$((num1 + num2))
# 2 和 4 都是字符在数组的位置,从 1 开始数,逗号两边不能有空格
echo $str[2,4]
# -1 是最后一个字符
% echo $str[4,-1]
变量比较
# 比较数值
num=123
# (( )) 用于数值比较等操作,如果为真返回 0,否则返回 1
# && 后边的语句在前边的语句为真时才执行
# 双等号可以替换成单等号,可以根据自己的习惯选用,其他多数地方也是如此
((num == 123)) && echo good
# (( 里边可以使用与(&&)或(||)非(!)操作符,同 c 系列语言
((num == 1 || num == 2)) && echo good
# 比较字符串
# 比较字符串要用 [[,内侧要有空格,字符串最好用引号包含,避免产生语法错误
[[ "$str" == "abc" ]] && echo good
# 可以和空字符串 "" 比较,未定义的字符串和空字符串比较结果为真
# [[ 里也可以用 && || !,但不能随意加小括号,[[ 的用法比 (( 要严格很多
[[ "$str" == "" || "str" == "123" ]] && echo good
条件语句
if [[ ]] {
} elif {
} else {
}
# elif 也可以写作 else if
注意尽量不要用 [[ ]] 比较数值,因为数值可能会被转化成字符串来比较
# 样例
if [[ "$str" == "name" || "$str" == "value" ]] {
echo "$str"
}
(( )) 用于比较数值,里边可以调用各种数值相关的函数,格式类似 c 语言,变量前的 $ 可省略。
# 格式
if (( )) {
}
# 样例
if ((num > 3 && num + 3 < 10)) {
echo $num
}
{ } 用于在当前 shell 运行命令并且判断运行结果。
# 格式
if { } {
}
# 样例
if {grep sd1 /etc/fstab} {
echo good
}
() 用于在子 shell 运行命令并且判断运行结果,用法和 {} 类似
# 格式
if ( ) {
}
# 混合使用
if [[ ]] && (( )) && { } {
}
循环语句
# 格式
while [[ ]] {
break/continue
}
# 样例 死循环
while (( 1 )) {
echo good
}
# until 和 while 相反,不满足条件时运行
until [[ ]] {
}
# for 循环主要用于枚举,
# 这里的括号是 for 的特有用法,不是在子 shell 执行。
# 括号内是字符串(可放多个,空格隔开)、数组(可放多个)或者哈希表(可放多个,哈希表是枚举值而不是键)。i 是用于枚举内容的变量名,变量名随意。
for i ( ) {
}
# 样例
for i (aa bb cc) {
echo $i
}
# 枚举当前目录的 txt 文件
for i (*.txt) {
echo $i
}
# 枚举数组
array=(aa bb cc)
for i ($array) {
echo $i
}
# c 风格 for 循环
for (( ; ; )) {
}
# 样例
for ((i=0; i < 10; i++)) {
echo $i
}
for i ({1..10}) {
echo $i
}
# repeat 语句用于循环固定次数,n 是一个整数或者内容为整数的变量。
repeat n {
}
# 样例
repeat 5 {
echo good
}
分支语句
# 格式 + 样例
case i {
(a)
echo 1
;;
(b)
echo 2
# 继续执行下一个
;&
(c)
echo 3
# 继续向下匹配
;|
(c)
echo 33
;;
(d)
echo 4
;;
(*)
echo other
;;
}
;; 代表结束 case 语句,;& 代表继续执行紧接着的下一个匹配的语句(不再进行匹配),;| 代表继续往下匹配看是否有满足条件的分支。这个是比较特别的。
用户输入选择语句
select 语句是用于根据用户的选择决定分支的语句,语法和 for 语句差不多,如果不 break,会循环让用户选择。
# 格式
select i ( ) {
}
# 样例
select i (aa bb cc) {
echo $i
}
将输出 1) aa 2) bb 3) cc ?# 按上边的数字回车来选择。
异常处理语句
# 如果语句1出错,则执行语句2
{
语句1
} always {
语句2
}
简化的条件语句
#针对只有一个分支的情况
[[ ]] || {
}
[[ ]] && {
}
三、字符串处理
字符串长度
str=abcde
echo $#str
# 读取函数或文件第一个参数的长度
echo $#1
字符串拼接
str1=abc
str2=def
str2+=$str1
str3=$str1$str2
字符串切片
str=abcdef
echo $str[2,4] #bcd
echo $str[2,-1] #bcdef
字符串截断
str=abcdeabcde
# 删除左端匹配到的内容,最小匹配
echo ${str#*b} #cdeabcde
# 删除右端匹配的内容,最小匹配
echo ${str%d*} #abcdeabc
# 删除左端匹配到的内容,最大匹配
echo ${str##*b} #cde
# 删除右端匹配到的内容,最大匹配
echo ${str%%d*} #abc
字符串查找
str=abcdef
echo $str[(I)cd] #3
# I是从右往左找,如果找不到则为0
echo $str[(I)cdd] #0
(( $str[(I)cd] )) && echo good #good
# i是从左往右找,找不到则返回数组大小+1
echo $str[(i)cd] #3
echo $str[(i)cdd] #7
遍历字符
str=abcd
for i ({1..$#str}) {
echo $str[i]
}
字符串替换
str=abcabc
# 只替换找到的第一个
echo ${str/bc/ef} #aefabc
# 删除匹配到的第一个
echo ${str/bc} #aabc
# 替换所有找到的所有
echo ${str//bc/ef} #aefaef
# 删除匹配到的所有
echo ${str//bc} #aa
str=abcABCabcABCabc
# 只从字符中开头开始匹配
echo ${str/#abc/123} #123ABCabcABCabc
# 只从字符串结尾匹配
echo ${str/%abc/123} #abcABCabcABC123
str=abc
# 如果匹配不到,则输出原字符串
echo ${str:#ab} #abc
# 加M后效果反转,匹配不到则输出空
echo ${(M)str:#ab}
按位置删除
str=abcdef
# 删除指定位置字符
str[1]=
echo $str #bcdef
# 删除多个
str[2,4]= #bf
按位置替换
str=abcdefg
# 一对一替换
str[2]=1 # str=a1cdefg
# 多对多替换
str[2,3]=2345 # str=a2345defg
判断是否存在
(( $+str )) && echo good #返回空
str=""
(( $+str )) && echo good #返回good
匹配判断
str1=abcd
str2=bc
[[ "$str1" == *"$str2"* ]] && echo good # good
正则表达式匹配
str=abc55def
[[ "$str" =~ "c[0-9]{2}\de" ]] && echo a # a
大小写转换
str="ABCDE abcde"
echo ${(U)str} --- ${str:u} #ABCDE ABCDE --- ABCDE ABCDE
echo ${(L)str} --- ${str:l} #abcde abcde --- abcde abcde
# 首字母大写
echo ${(C)str} # Abcde Abcde
目录文件名截取
filepath=/a/b/c.x
# :h 取目录名
echo ${filepath:h} #/a/b
# :t 取文件名
echo ${filepath:t} #c.x
# :e 取文件扩展名,如果没有则为空
echo ${filepath:e}
字符串分隔
str='aa bb cc dd'
echo ${str[(w)2]} #bb
echo ${str[(w)3]} #cc
str='aa--bb--cc'
echo ${str[((ws:--:)3)]} #指定分隔符
多行字符串
str="line1
> line2"
读取文件内容到字符串
#比用str=$(cat filename)性能好很多
str=$(<filename)
echo "$(<filename)"
#遍历每行
for i (${(f)"$(<filename)"}) {
echo $i
}
读取文件指定行
#读取第二行
echo ${"$(<test.txt)"[(f)2]}
#输出包含ang的第一行
echo ${"$(<test.txt)"[(fr)*ang*]}
#输出包含pp的第一行,但从左截掉line 4个字符。
echo ${"$(<test.txt>)"[(fr)*pp*]#line}
读取进程输出到字符串
类似于文件,将$(<test.txt)换成$(命令)即可。
四、字符串处理:转义符和格式化输出
\n 换行
\r 回车
\t Tab
\\ \
\` `
可用hexdump命令查看字符的ASCII码值: echo ab= | hexdump -C 将显示abc及换行符的ASCII码
#-r 代表忽略字符串中的转义符
#${((q))str} 为字符串中的特殊符号添加转义符号
print -r ${((q))str}
单引号
#用双引号包含单引号
echo "a'b"
#用转义符
echo a\`b
双引号
#使用变量
echo "$str"
#运行命令
echo "$(ls)"
#用``运行命令
echo "`date`"
#使用$(())计算数值
echo "$(( 1+2 ))"
#使用$[]计算数值
echo "$[1+2]"
反引号
反引号是用来运行命令的,返回结果到变量等。反引号的功能和$()功能基本一样,但$()可以嵌套
str=`ls`
print命令用法
-l 分行输出字符串
print -l aa bb
array=(aa bb)
print -l $array
``
-n 不再输出内容的末尾自动添加换行符
-m 用于只输出匹配到的字符串
print -m “aa*” aabb abc aac #aabb aac
-o 字符串升序
-O 字符串降序
-i 对大小写不敏感
-r 不对字符串进行转义
-c 字符串按列输出
-C 按指定列数输出字符串
-D 将符合条件的路径名转化成带~的格式,即相对于HOME目录的路径
-N 将输出的字符串以\x00分隔
-x 将行首的Tab换成空格
-X Tab换成空格,带空格补全
-u 指定fd输出,默认输出到fd 1,即stdout。2是stderr
-v 把输出内容保存到变量
print -v str aa bb cc echo $str
-s/-S 用于把字符串保存到历史记录
-z 把字符串输出到命令行编辑区
-f 按指定格式输出,同printf
-P 输出带颜色和特殊样式的字符串
**printf命令**