Shell之海量数据处理grep,cut,awk,sed
GREP
grep命令是Globally search a Regular Expression and Print的缩写,表示进行全局的正则匹配并进行打印。grep的相关扩展命令包括egrep和fgrep,其中egrep支持更多的正则匹配,fgrep只进行字符的匹配,不支持正则表达式。
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
OPTIONS:
-n 匹配的行数也展示出来
-A 3 将匹配之后的3行也展示出来
-B 3 将匹配之前的3行业展示出来
-o 仅输出匹配的部分
-v 反向匹配
-f 指定需要匹配的文件
root@dev02:/usr/local/shell# cat 1.txt 123 345 root@dev02:/usr/local/shell# cat 2.txt abc bcd 123 haha hehe 23456 hello abcd root@dev02:/usr/local/shell# grep -w -A1 -B2 -n 123 2.txt 1-abc 2-bcd 3:123 4-haha root@dev02:/usr/local/shell# grep -n -f 1.txt 2.txt 3:123 6:23456
CUT
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出,即对列进行提取。
cut [OPTIONS] file1 file2
-d delimiter 指定分隔符,不加时默认为制表符
-f fields 依据 -d 的分隔字符将一段信息分割成为数段,用 -f 取出第几段的意思 1,3 指1列和3列;1-3 指1列到3列;1- 指1列到最后一列
-c characters 以字符的单位取出固定字符区间
查询所有可登录的普通用户 root@dev02:/usr/local/shell# grep '/bin/bash' /etc/passwd | cut -d ':' -f 1 | grep -v root ubuntu postgres ftpUse
SED
Stream Editor. sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作。
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
选项与参数:
-n :在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。
function:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除, d 后面通常不接任何参数;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g /g表示全部;没有表示指替换第一个
eg:打印磁盘信息的1-最后一行 root@dev02:/usr/local/shell# df -h|sed -n '1,$p' Filesystem Size Used Avail Use% Mounted on udev 16G 0 16G 0% /dev tmpfs 3.2G 299M 2.9G 10% /run /dev/vda1 97G 33G 65G 34% / tmpfs 16G 28K 16G 1% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 16G 0 16G 0% /sys/fs/cgroup tmpfs 3.2G 0 3.2G 0% /run/user/1001 eg:搜索/etc/passwd,找到root对应的行,执行后面花括号中的一组命令,每个命令之间用分号分隔,这里把bash替换为blueshell,再输出 root@dev02:/usr/local/shell# nl /etc/passwd | sed -n '/root/{s/bash/blueshell/;p}' 1 root:x:0:0:root:/root:/bin/blueshell
AWK
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
调用方式
1.命令行方式
awk [-F field-separator] 'commands' input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。
2.将所有的awk命令插入一个单独文件
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。
3.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk
脚本格式
awk 'BEGIN{ commands } pattern{ commands } END{ commands }' file
一个awk脚本通常由BEGIN, 通用语句块,END语句块组成,三部分都是可选的。 脚本通常是被单引号或双引号包住。
BEGIN语句块:在awk开始从输入输出流中读取行之前执行,在BEGIN语句块中执行如变量初始化,打印输出表头等操作。
pattern语句块:pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行。{ }类似一个循环体,会对文件中的每一行进行 迭代,通常将变量初始化语句放在BEGIN语句块中,将打印结果等语句放在END语句块中。
END语句块:在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。
eg:查询ftp用户 root@dev02:/usr/local/shell# cat 1.sh #!/bin/awk cat /etc/passwd | grep ftp |awk -F ':' 'BEGIN {count=0;print "name";} {count++;print $1;} END{print "total: " count}'; echo '-----------' root@dev02:/usr/local/shell# sh 1.sh name ftp ftpUser ftp1 total: 3 -----------
比较运算符
数字比较:> < >= <= == !=
字符匹配:some_value ~ / pattern/ (匹配) some_value !~ / pattern/ (不匹配) 在 awk 中,只有使用"//"包含的字符串,awk 命令才会査找
df -h | awk '$0~/tmp/ {print $1 " " $5 }' 等价于 df -h | awk '/tmp/ {print $1 "-" $5 }'
root@dev02:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 16G 0 16G 0% /dev
tmpfs 3.2G 299M 2.9G 10% /run
/dev/vda1 97G 33G 65G 34% /
tmpfs 16G 28K 16G 1% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 16G 0 16G 0% /sys/fs/cgroup
tmpfs 3.2G 0 3.2G 0% /run/user/1001
tmpfs 3.2G 0 3.2G 0% /run/user/1005
tmpfs 3.2G 0 3.2G 0% /run/user/1002
root@dev02:~$ df -h | awk '/tmp/' | awk '$3==0 {print $1 " full"} $3!=0 {print $1 " " $3} '
tmpfs 299M
tmpfs 28K
tmpfs full
tmpfs full
tmpfs full
tmpfs full
tmpfs full
使用shell变量
1.通过命令行参数定义变量时引用
awk -v awk变量名= shell变量名
2.在awk中直接引用
root@dev02:/usr/local/shell# cat 2.sh #!/bin/awk ### 读取输入的用户名信息,找到匹配的用户 read -p "请输入用户名:" username cat /etc/passwd | awk /$username/ | awk -F : '{ print $1 }' root@dev02:/usr/local/shell# sh 2.sh 请输入用户名:ftp ftp ftpUser ftp1