shell脚本杂记(三)

1,我们先来熟悉下正则表达式一些字符含义的基础
^行起始标记
$行尾标记
.匹配任意一个字符
[]匹配包含在[]之中的任意一个字符
[^]匹配除[^字符]之外的任意一个字符 9[^01],可以匹配92,93不会匹配90,91
[-]匹配指定范围内的字符,[1-8]匹配1-8之内的任意一个字符
?匹配0次或1次
+匹配1次或多次
*匹配0次或多次
()创建一个匹配的字串
{n}匹配n次
{n,}至少n次
{n,m}n和m之间
|或关系的匹配 ba(r|t)可以匹配bar和bat
\转义字符a\.b匹配a.b

2,grep命令用法:
grep pattern filename  单个文件
grep pattern file1 file2 file3 ...  多个文件
egrep "[a-z]+" file 扩展的正则
egrep -o "[a-z]" 只输出匹配部分
grep -v pattern file 匹配结果反转
grep -c patter file 匹配行数

递归搜索在多级目录里搜索文件:
grep "text" . -R -n

忽略大小写
grep -i "helloW"

匹配多个样式
grep -e "this"  -e "key" -o

在搜索里排除,或指定文件
grep "main" . -r --include *.{c,cpp}
grep "main" . -r --exclude *.{c,cpp}

打印匹配之后的行:
[root@ganglia 916]# seq 10 | grep 5 -A 2
5
6
7
[root@ganglia 916]# 


匹配结果前2行
[root@ganglia 916]# seq  10 | grep 5 -B 2
3
4
5
[root@ganglia 916]# 



匹配结果前后2行
[root@ganglia 916]# seq 10 | grep 5 -C 2
3
4
5
6
7
[root@ganglia 916]# 


3,使用cut命令,cut命令是用来切分分文件的,很容易的按列切分

1,提取特定的字符 cut -f filed_list filename
例如: cut -f 2,3 filename

[root@ganglia 916]# cut -f1 -d" " a.txt 
name
zhang
wang
li
[root@ganglia 916]# 

-d后面指定定界符
-f后面多个数字使用逗号隔开

[root@ganglia 916]# cut -f1,3 -d" " a.txt 
name score
zhang 100
wang 99
li 96
[root@ganglia 916]# cat a.txt 
name mark score
zhang 20 100
wang 36 99
li 12 96
[root@ganglia 916]# 




其他用法:
N- 从第N个字节,字符或字段到行尾
N-M 从第N个字节到第M个字节
-M 从第一个字节到第M个字节

-b表示字节
-c表示字符
-f用于定义字段



打印前5个字符:
[root@ganglia 916]# cat b.txt 
aafgdfdfdfdsfd
dffdsfag12343r3
fdfdfdgfgfgf
dfdgdtrasf
zzzzzzzz
ddfdfggdfdf
[root@ganglia 916]# cut -c1-5 b.txt 
aafgd
dffds
fdfdf
dfdgd
zzzzz
ddfdf
[root@ganglia 916]# 


打印前2个字符:
[root@ganglia 916]# cut b.txt -c -2
aa
df
fd
df
zz
dd
[root@ganglia 916]# 


提取多个字段输出:

[root@ganglia 916]# cut b.txt  -c1-3,4-6 --output-delimiter "====>"   
aaf====>gdf
dff====>dsf
fdf====>dfd
dfd====>gdt
zzz====>zzz
ddf====>dfg
[root@ganglia 916]# 



4,使用sed命令
替换命令sed 's/pattern/replace/' file
替换原始文本 sed -i 's/pattern/replace/' file
替换所有目录sed -i 's/pattern/replace/g' file
移除空白行 sed '/^$/d' file
已匹配字符串标记,这个功能,做高亮最适用了:
 

[root@ganglia 916]# echo "i am a red cat" | sed 's/red/\<bold\>&\<\/bold\>"/g'
i am a <bold>red</bold>" cat
[root@ganglia 916]# echo "i am a red cat" | sed 's/red/"&"/g'                
i am a "red" cat
[root@ganglia 916]#

多个表达式命令: sed -e "pattern1" -e "pattern2"

在shell里面向sed里,传变量
[root@ganglia 916]# text=hello
[root@ganglia 916]# echo hello world | sed "s/$text/big/"
big world
[root@ganglia 916]# 


5,使用awk编程

基本语法: awk 'BEGIN {print "start"} pattern {commonds} END {print "end"}  ' files

注意awk的脚本,也可以用双引号括住
如下例子:
awk "BEGIN {i=0} {i++} END {print i}" filename
[root@ganglia 916]# echo -e "1\n2\n3" | gawk 'BEGIN {print "开始" } {print} END {print "结束"} '
开始
1
2
3
结束
[root@ganglia 916]#


需要记住两点,print打印的参数是逗号分割的,默认空格是定界符 双引号,会被当做拼接符号

NR 记录数量,相当于当前行号
NF 字段数量,执行过程中当前字段数
$0 原始内容
$n 第n列


[root@ganglia 916]# cat a.txt 
name mark score
zhang 20 100
wang 36 99
li 12 96
[root@ganglia 916]# gawk '{ print $1, $3}' a.txt 
name score
zhang 100
wang 99
li 96
[root@ganglia 916]# 


打印行号,统计行数
[root@ganglia 916]# gawk '{ print NR }' a.txt        
1
2
3
4



读取一行使用getline
[root@ganglia 916]# seq 6 | gawk 'BEGIN {getline; print "第一行:" $0} {print $0}'
第一行:1
2
3
4
5
6
[root@ganglia 916]# 


注意,这个例子,可以用来读取带表头的excel或者一些文本数据非常方便


awk的灵活的过滤条件
awk 'NR < 5' 行号小于5的行
awk 'NR==1,NR==4' 行号在1到5之间的行
awk '/linux/' 包含linux的行
awk '!/linux/' 不包含linux的行

设置字段定界符:
awk -F: '{ print $NF}' /etc/passwd

awk支持循环:
[root@ganglia 916]# gawk  'BEGIN{ for (i=0;i<=10;i++){ print i  } }'
0
1
2
3
4
5
6
7
8
9
10
[root@ganglia 916]# 

跟我们所学的C和JAVA还是JavaScrpit都非常接近

awk内置函数
length()字符串长度
index()返回出现位置
split()打散一个数组
substr()截取一个字符串
sub() 替换
match()匹配




6,按列合并多个文件

[root@ganglia 916]# cat c.txt 
1
2
3
4
[root@ganglia 916]# cat d.txt 
a
b
c
d
e
[root@ganglia 916]# pas
passwd  paste   
[root@ganglia 916]# pas
passwd  paste   
[root@ganglia 916]# paste c.txt  d.txt 
1       a
2       b
3       c
4       d
        e
[root@ganglia 916]# 


指定分割符:
[root@ganglia 916]# paste c.txt  d.txt -d ","      
1,a
2,b
3,c
4,d
,e
[root@ganglia 916]# 


截取指定范围字符
[root@ganglia 916]# seq 100 | gawk 'NR==4,NR==10'
4
5
6
7
8
9
10
[root@ganglia 916]# 


逆序输出tac
[root@ganglia 916]# seq 5 | tac
5
4
3
2
1
[root@ganglia 916]# 


逆序输出awk
[root@ganglia 916]# seq 5 | gawk '{ lifo[NR]=$0 } END{ for(lno=NR;lno>-1;lno--){print lifo[lno]} } ' 
5
4
3
2
1

[root@ganglia 916]# 





猜你喜欢

转载自qindongliang.iteye.com/blog/2117163