如要下载笔记和代码请到我的github。
欢迎访问我的主页查看更多文章。
/usr/share/dict/words
中“a开头、t结尾”的单词,采用命令如下:$ egrep "^a.*t$" /usr/share/dict/words # egrep比grep支持更多正则表达式规则,此处grep也可以
# 如果我们要统计总的单词数
$ egrep '^a.*t$' /usr/share/dict/words | wc -c
.
:匹配换行符之外的任意一个字符,.
能匹配的字符范围是最大的;[]
:指定一个字符集,要求只能匹配其中的一个字符,如[abc]
表示三选一;-
:连字符,和[]
配合使用,如[a-zA-Z]
表示匹配一个字母;\<
和\>
:一对分隔符,表示匹配一个单词,注意正则表达式中对单词的定义指的是两侧由非单词字符分隔的字符串(非单词字符指的是字母、数字、下划线以外的任何字符);类 | 匹配字符 |
---|---|
[[:alnum:]] | 字母、数字字符 |
[[:alpha:]] | 字母字符 |
[[:lower:]] | 小写字母 |
[[:upper:]] | 大写字母 |
[[:digit:]] | 小数 |
[[:xdigit:]] | 十六进制数字 |
[[:punct:]] | 标点符号 |
[[:blank:]] | 制表符和空格 |
[[:space:]] | 空格 |
[[:cntrl:]] | 所有控制符 |
[[:print:]] | 所有可打印字符 |
[[:graph:]] | 除空格外所有可打印字符 |
- 位置匹配:
- ^
:用于匹配行首;
- $
:用于匹配行尾。
- 所以如果要匹配一个空行就用^$
,两者不必非要一起使用。
- 字符转义:
- \
:当要匹配特殊字符本身时,就在前加上转义字符,取消元字符本身的特殊含义。
- 重复:
- *
:表示在*
前面的模式应该重复0次或多次;
- +
:表示模式重复1次或多次;
- ?
:重复0次或1次;
- {n}
:模式重复n次;
- {n,}
:模式重复n次或更多;
- {n,m}
:模式不少于n次,不多于m次。
- 一个例子,匹配不少于8位的数\<[1-9][0-9]{7,}\>
。
- 子表达式,i.e.”分组”:
- ()
:将部分字符组成一个字符组作为一个子模式,如”(or){2,}”表示整个子字符组重复2次以上,否则只重复紧挨的字符r。
- 反义(^
在行首表示位置匹配,放括号内表示反义):
- ^
:除了此字符以外,全部都可以,和[]
配合使用,表示除括号内字符的任意一个其他字符。如[^ya]
表示除y和a以外的任一字符。
- 分支,或者叫“或”逻辑(一般正则表达式总是执行“与”逻辑,指同时满足给出的若干条件):
- |
:如^h|h$
表示h开头”或”h结尾,而^hh$
表示h开头”且”h结尾(即’hh’),一个表达式中可以出现多个或逻辑Jan(uary| |\.)
。
- 逆向引用:子表达式中捕获的内容可以在正则表达式的其他地方再次使用;
- \n
:’反斜杠+编号n’表示第n组子表示匹配到的内容,如(\<*.\>).?( )*\1
可以匹配如’cart cart’,’ha!ha’这些字符组;
- 从左到右,第i个出现的子表达式编号为i。
/bin/bash
,子/父shell是指他们之间的调用关系。#!
开头,指定脚本的运行环境,#! /bin/bash
告诉shell运行此脚本应该使用的shell(可以省略但不是一个好习惯);#
表示注释;echo
执行时会自动加上一个换行符;chmod a+x hello
/chmod +x hello
。#! /bin/bash
#Display a line
echo 'Hello world!' #echo会在最后自动加上一个换行符
=
:赋值符号,如var=1
就是给var赋值,注意’=’两边不能有空格;$
:shell编程中用于对一个变量进行解析,表示取得变量的值;source
/.
:一般变量只在其所在的”脚本”中有效,shell中不可见其值,但source
命令可以让一个脚本影响其父Shell环境(当前执行脚本的shell及其父shell),使值在shell中可见;export
:可以让脚本影响其子shell环境(子shell是在执行脚本中sh
命令调用的shell);export
,在shell中要影响配置脚本用source
;unset
:手动注销一个变量。\
:转义字符,如果要输出特殊字符时使用(类所有编程语言),如\$
输出美元符号;{}
:限定变量的开始和结束(类python),如:#! /bin/bash
word="big"
echo "The apple is ${word}."
$0
:表示第一个命令行参数,这个参数总是脚本的名字;$n
:表示第n个参数(不包括脚本名);${n}
:当n为一位数以上时,需要用大括号将位置序号括起来;$*
/$@
:参数列表(不包括脚本名);$#
:包含参数个数(参数列表长度)。#!/bin/bash
# 是$@最常见的用法
#! /bin/bash
echo "$# files to list:"
for file in $@
do
ls -l $file
done
""
:双引号,阻止Shell对大多特殊字符(如#)进行解释,但$//"仍保持其特殊含义;
:单引号,阻止shell对所有字符进行解释;
()
改变优先级;=
和==
表示,因为=
赋值时两边无空格(因为变量不是命令不能分开,而整个语句才能算是一个命令),而表示比较时两边有空格。$[]
:求值后整体赋值。 [base#]n
可以表示从2到36进制的任何一个n值(默认十进制),如2#10表示二进制数10;$[]
可以接受不同基数的数字求值;1+2
,因为shell是一种弱类型的语言,换言之shell不知道num的类型,因此只能简单取得$num将整个表达式赋值。如果按第二段就能计算后再输出结果。#! /bin/bash
num=1
# ouput 1+2
num=$num+2
echo $num
# output 3
num=$[num]
expr
命令也对表达式执行求值操作,可以允许更复杂的表达式。let
:此命令也指导shell进行表达式求值,功能类似$[]
,命令右边的表达式不能有空格,如let num=$num+1
会输出值而非表达式。if-then-fi
; bash
if test-commands
then
commands
fi
if-then-elif-then-else-fi
,当然各条件语句之间必须互斥; bash
if test-command-1
then
commands-1
elif test-command-2
then
commands-2
elif test-command-3
then
commands-3
else
commands-4
fi
#! /bin/bash
# if例子
echo "Enter password:"
read password
echo $password
if [ "$password" = john ];then
echo "Hello John"
elif [ "$password" = mike ];
then
echo "Hello Mike"
elif [ "$password" = lewis ]
then
echo "Hello Lewis"
else
echo "I don't know you,go away"
fi
bash
case word in
pattern1)
commands1
;;
pattern2)
commands2
;;
...
patternN)
commandsN
;;
esac
;;
相当于C语言中的break
,shell遇见时会跳转到case结构的最后,但是Shell中;;
是不能省略的;*)
,因*
用于匹配所有的字符串;#! /bin/bash
# an example of case
# note $n means nth input params
# 重写if例子
case $1 in
john)
echo "Hello John!"
;;
mike)
echo "Hello Mike!"
;;
lewis)
echo "Hello Lewis!"
;;
*)
echo "Go away!!"
;;
esac
if
判断的依据是程序的返回值(0为真/正常,非0为假/出错序号): if
接受一个程序名作为参数,根据执行程序的返回值判断是否执行:#!/bin/bash
if ./testscript -1
then
echo "testscript exit -1"
fi
if ./testscript 0
then
echo "testscript exit 0"
fi
if ./testscript 1
then
echo "testscript exit 1"
fi
#----------testscript--------
#!/bin/bash
#表示退出并返回输入所有参数
exit $@
test
命令和空格的使用: test
:if语句既然只接受程序名为参数,所以if的条件判断需要引入一个特定的命令即test
,也是[
方括号的同义词;test
和[
都是/usr/bin
下的命令,而判断的字符串(…)和=
及]
都是要求输入的参数,参数之间必须要空格分开(!!在赋值语句中=
两边一定没有空格);test
/[
命令可以对以下3类表达式进行测试(可以在man test
中看到详细内容): ""
不是必要的,因为Bash会自动给没有值的变量加上引号(但是有些shell不如此),为保证清晰性和可移植性应为字符串变量加上引号。选项 | 描述 |
---|---|
-z str | 当字符串str长度为0时返回真 |
-n str | 当字符串长度不为0时返回真 |
str1 = str2 | 相等时返回真 |
str1 != str2 | 不等时返回真 |
- 文件测试:用于判断一个文件是否满足特定的条件;
选项 | 描述 |
---|---|
-d pathname | 是目录时返回真 |
-e pathname | 指定文件或目录存在时为真 |
-f file | 是常规文件(非符号链接、管道、目录等)时为真 |
-h file | 是符号链接文件时返回真 |
-[rwx] pathname | 当指定的文件或目录设置了可[读 写 执行] |
- 数字比较:只能用于比较正/负整数test int1 option int2
/[ int1 option int2 ]
;
选项 | 描述 |
---|---|
-eq | int1 == int2 |
-ne | int1 != int2 |
-lt | int1 < int2 |
-gt | int1 > int2 |
-le | int1 <= int2 |
-ge | int1 >= int2 |
- 复合表达式:用逻辑(与或非)串起的多个表达式;
- 注意:Shell的内建条件操作符&&
或||
可以代替下面的-a
和-o
;前者连接两条[
或test
语句,逻辑清晰;后者只用一条[
/test
语句,执行效率相对更高;如`[ -f $@ -a -x /usr/bin/vim ]`等于[ -f $@ ] && [ -x /usr/bin/vim ]
.
操作符 | 描述 |
---|---|
!expr | “非”运算 |
expr1 -a expr2 | “与”运算 |
expr1 -o expr2 | “或”运算 |
$
符号;while
语句: bash
while test-commands
do
commands
done
while
语句的测试条件除了使用test
,[
函数,还可以利用函数read
等的返回值。until
语句:和while
功能完全一样,但是测试条件相反。 bash
until test-commands
do
commands
done
for
语句:从列表/值表中逐一读取值进行操作,直到取完所有的值; seq
:此命令自动接受一个参数n,产生1到n(均包含)的值表;bash
for variable [in list]
do
commands
done
read
:读取用户输入; REPLY
中;read
常用来在输出一段内容后暂停,等待用户的下一步指令(如“继续”)。exit
:强行退出一个脚本,并向调用脚本的父进程返回一个整数值; exit n
。trap
:用于捕捉一个信号,如进程通信中,用于捕捉且忽视一个信号; trap
要置于文件首才能捕获信号;kill -l
获取(INT为’Ctrl+c’,EXIT为’Ctrl+D’);trap 'commands' SIGNAL
。&&
和||
用于创建命令表:命令表利用前一个命令的退出值来控制是否执行另一条命令,命令会被自动识别寻找参数输入。
;
顺序命令表已经在if
等语句中出现过):表现形式 | 说明 |
---|---|
a&&b | “与”命令表。当且仅当a执行成功,才执行b |
a | |
a;b | 顺序命令表。先执行a,再执行b |
source
命令。
#!/bin/bash
dirname=~/LearningNotes/git
#echo $dirname
test -d $dirname && cd $dirname
cut
:从输入行中提取指定部分;-c
:提取一行中指定范围的字符,如cut -c3-6 file_name
;-f
:提取指定行中指定的字段,分隔符用-d
指定(否则默认使用TAB),如cut -d" " -f2 file_name
截取第2个字段。diff
:用于确定两个版本的源文件存在哪些修改;diff file1 file2
。sort
:以行为输入单位,对其按照字母顺序进行排列;-r
:默认按字母升序排列,-r
使按降序排列;-k
:默认按照第1个字段执行排序,-k
可以指定按第字段排序。uniq
:从已排好序的输入行中删除重复的行,通常和sort
命令结合管道工作。tr
:按照用户指定方式对字符执行替换,结果输送到标准输出;tr "ABH" "HCA" < file
:ABH分别替换为HCA;tr "ABC" "[Z*]" < file
/tr "A-C" "[Z*]" < file
:替换成”Z”;tr --delete " " < file
:删除空格。wc
:用来统计文件中字节、单词和行的数量;选 项 | 描 述 |
---|---|
-c /--bytes |
显示字节数 |
-l /--lines |
显示行数 |
-L /--max-line-length |
显示最长一行的长度 |
-w /--words |
显示单词个数 |
--help |
显示帮助 |
- substr
:从字符串提取一部分,是shell内建的运算符,必须使用expr
进行表达式求值;
- 依次接受3个参数:(1)字符串/存放字符串的变量;(2)提取开始的位置(从1开始计数);(3)需要提取的字符数。
- 用法:expr substr "Hello World" 1 5
。
- seq
:用于产生一个整数数列;
- 只指定结束值:seq
产生从1到的数列;
- 指定开始和结束:seq
产生从到的数列;
- 指定开始结束和步长:seq
。
printenv
查看当前Shell的所有环境变量。PATH
:搜索路径,是最常用的环境变量之一,这个变量告诉Shell在什么地方查找用户要求执行的程序;\ PATH
变量用一系列冒号分隔各目录,用户如果没有命令完整路径,Shell会依次在PATH变量指定的目录中查找;PATH=$PATH:/usr/local/bin
;./program
一是为了安全,在安全性要求更高的场合应该输入完全路径;二是因为命令通常在PATH中搜索,所以要加上./
目录才能运行。alias
:设置命令(即程序)别名; alias ll='ls -l'
。~/.bashrc
:Shell为每个用户维护了一个配置文件,对当前用户有效,推荐;/etc/bash.bashrc
:全局shell配置文件,对所有用户有效。source
命令生效。Linux从入门到精通 刘忆智 著