Linux 脚本语言Shell编程
1. 正则表达式
1.1 正则表达式与通配符
-
正则表达式
- 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。
- grep、 awk、sed等命令可以支持正则表达式。
-
通配符
- 通配符用来匹配符合条件的文件名,通配符是完全匹配。
- ls、 find、 cp这些命令不支持正则表达式,所以只能使用shell自己的通配符来进行匹配了。
1.2 基础正则表达式
元字符 | 作用 |
---|---|
* |
前一个字符匹配0次或任意多次。 |
. |
匹配除了换行符外任意一个字符。 |
^ |
匹配行首。例如: ^ hello会匹配以 hello 开头的行。 |
$ |
匹配行尾。例如: hello$ 会匹配以 hello 结尾的行。 |
[] |
匹配中括号中指定的任意一个字符,只匹配一个字符。例如: [aoeiu] 匹配任意一个 元音字母,[0-9] 匹配任意一位数字,[a-z] [0-9]匹配小写字和一位数字构成的两位字符。 |
[^] |
匹配除中括号的字符以外的任意一个字符。例如: [^0-9] 匹配任意一位非数字字符, [^a-z] 表示任意一位非小写字母。 |
\ |
转义符,用于取消特殊符号的含义。 |
\{n\} |
表示其前面的字符恰好出现n次。例如: [0-9]\{4\} 匹配4位数字。[1][3-8][0-9]\{9\} 匹配手机号码。 |
\{n,\} |
表示其前面的字符出现不小于n次。例如: [0-9]\{2,\} 表示两位及以上的数字。 |
\{n,m\} |
表示其前面的字符至少出现n次,最多出现m次。 例如: [a-z]\{6,8\} 匹配6到8位的小写字母。 |
-
*
#前一个字符匹配0次,或任意多次。grep "a*" test_rule.txt #匹配所有内容,包括空白行 grep "aa*" test_rule.txt #匹配至少包含有一个a的行 grep "aaa*" test_rule.txt #匹配最少包含两个连续a的字符串 grep "aaaaa*" test_rule.txt #则会匹配最少包含四个连续a的字符串
-
.
#匹配除了换行符外任意一个字符。grep "s..d" test_rule.txt #会匹配在s和d这两个字母之间一定有两个字符的单词 grep "s.*d" test_rule.txt #匹配在s和d字母之间有任意字符 grep ".*“ test_rule.txt #匹配所有内容
-
^
、$
#^
匹配行首,$
匹配行尾。grep "^M"' test_rule.txt #匹配以大写M开头的行 grep "n$" test_rule.txt #匹配以小写n结尾的行 grep -n "^$" test_rule.txt #会匹配空白行
-
[]
#匹配中括号中指定的任意一个字符,只匹配一个字符。grep "s[ao]id" test_rule.txt #匹配s和i字母中,要不是a、要不是o grep "[0-9]" test_rule.txt #匹配任意一个数字 grep "^[a-z]" test_rule.txt #匹配用小写字母开头的行
-
[^]
#匹配除中括号的字符以外的任意一个字符。grep "^[^a-z]" test_rule.txt #匹配不用小写字母开头的行 grep "^[^a-zA-Z]" test_rule.txt #匹配不用字母开头的行
-
\
#转义符。grep "\.$" test_rule.txt #匹配使用 “.” 结尾的行
-
\{n\}
#表示其前面的字符恰好出现n次。grep "a\{3\}" test_rule.txt #匹配a字母连续出现三次的字符串 grep "[0-9]\{3\}" test_rule.txt #匹配包含连续的三个数字的字符串
-
\{n,\}
#表示其前面的字符出现不小于n次。grep "^[0-9]\{3,\}[a-z]" test_rule.txt #匹配最少用连续三个数字开头的行
-
\{n,m\}
#匹配其前面的字符至少出现n次,最多出现m次。grep "sa\{1,3\}i" test_rule.txt #匹配在字母s和字母i之间有最少一个a,最多三个a
2 字符截取命令
2.1 cut 字段提取命令
cut
是字段提取命令。
cut [选项] 文件名
选项:
-f
列号 #提取第几列-d
分隔符 #按照指定分隔符分割列
案例1:cut -f 2 student.txt
# vi student.txt
ID Name gender Mark
1 Limng M M
2 Sc M 86
3 Gao M 83
# cut -f 2 student.txt
Name
Limng
Sc
Gao
案例2:cut -f 2,3 student.txt
# cut -f 2,3 student.txt
Name gender
Limng M
Sc M
Gao M
案例3:cut -d ":" -f 1,3 /etc/passwd
# cut -d ":" -f 1,3 /etc/passwd
root:0
bin:1
daemon:2
案例4:cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ":" -f 1
# cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ":" -f 1
user1
user2
user3
cut 命令的局限
不能以空格作为分隔符。
# df-h|cut-d " " -f 1,3
2.2 printf 命令
printf
是格式化输出命令。非常麻烦,但是 awk 命令识别它。
printf
[输出类型输出格式] [输出内容]
输出类型:
%ns
#输出字符串。n是数字指代输出几个字符%ni
#输出整数。n是数字指代输出几个数字%m.nf
#输出浮点数。m和n是数字,指代输出的总位数和小数位数。如%8.2f
代表共输出8位数,
其中2位是小数,6位是整数。
输出格式:
输出格式 | 说明 |
---|---|
\a | 输出警告声音 |
\b | 输出退格键,也就是Backspace键 |
\f | 清除屏幕 |
\n | 换行 |
\r | 回车,也就是Enter键 |
\t | 水平输出退格键,也就是Tab键 |
\v | 垂直输出退格键,也就是Tab键 |
案例1:
[root@localhost ~]# printf %s 1 2 3 4 5 6
123456[root@localhost home]#
[root@localhost ~]# printf %s %s %s 1 2 3 4 5 6
%s%s123456[root@localhost home]#
[root@localhost ~]# printf '%s %s %s' 1 2 3 4 5 6
1 2 34 5 6[root@localhost home]#
[root@localhost ~]# printf '%s %s %s\n' 1 2 3 4 5 6
1 2 3
4 5 6
案例2:
# cat student.txt
ID Name gender Mark Mysql Averager
1 Limng M M 86 87.66
2 Sc M 86 87 85.55
3 Gao M 83 93 92.66
不调整输出格式
# printf '%s' $(cat student.txt)
IDNamegenderMarkMysqlAverager1LimngMM8687.662ScM868785.553GaoM839392.66[root@localhost home]#
调整格式输出
# printf '%s\t %s\t %s\t %s\t %s\t %s\t \n' $(cat student.txt)
ID Name gender Mark Mysql Averager
1 Limng M M 86 87.66
2 Sc M 86 87 85.55
3 Gao M 83 93 92.66
awk 命令支持
在awk命令的输出中支持 print 和 printf 命令。Linux默认不支持 print 命令。
print
#print会在每个输出之后自动加入一个换行符(Linux默认没有print命令)printf
#printf是 标准格式输出命令,并不会自动加入换行符,如果需要换行,需要手工加入换行符
2.3 awk 命令
awk ‘条件1{动作1}条件2{动作2}..’
文件名
条件(Pattern) :一般使用关系表达式作为条件
x>10
//判断变量x是否大于10x>=10
//大于等于x<=10
//小于等于
动作(Action) :
- 格式化输出
- 流程控制语句
案例:
awk '{printf $2 "\t" $6 "\n"}'
student.txt
# awk '{printf $2 "\t" $6 "\n"}' student.txt
Name Averager
Limng 87.66
Sc 85.55
Gao 92.66
df -h | awk '{print $1 "\t" $3}'
# df -h | awk '{print $1 "\t" $3}'
Filesystem Used
/dev/mapper/VolGroup-lv_root
5.5G 4.6G
tmpfs 0
/dev/sda1 32M
BEGIN
awk 'BEGIN {printf "This is a transcript \n"}{printf $2 "\t" $6 "\n"}'
student.txt
# awk 'BEGIN {printf "This is a transcript \n"}{printf $2 "\t" $6 "\n"}' student.txt
This is a transcript
Name Averager
Limng 87.66
Sc 85.55
Gao 92.66
FS内置变量
# cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN {FS=":"}{printf $1 "\t" $3 "\n"}'
root 0
END
# awk 'END {printf "The End