先了解数据格式,再编写脚本处理数据。
tab补齐,双击tab列出候选项。
Shell通配符
*通配符匹配任意一个或多个字符
"?"通配符匹配一个任意字符(相比*存在数量限制)
[list] 匹配list中任意单个字符
正则表达式是以行为单位,一次处理一行。
linux中正则表达式仅受三剑客(sed,awk,grep)支持,其他命令无法使用(仅能使用通配符*)。
操作内容用正则,操作文件名用通配符
正则表达式分类
基本正则表达式
^$.[]*
扩展正则表达式
扩展正则必须用grep -E才能生效
grep不加参数,得在特殊字符前面加""反斜杠,识别为正则。
(){}?+|等字符
注意:grep是模糊过滤(包含则通过),实际上若要准确识别还要搭配awk的‘{if判断是否相等语句}‘进行精准过滤。
(查询文本)grep xxx:从stdin中读入若干行数据,如果某行中包含xxx,则输出该行(逐行输出);否则忽略该行。
可以配合ps,ls等stdout命令食用:查询进程/目录中是否存在对应进程和文件。
grep配合sort可以有序输出(默认按照第一列的ASCII 码次序排序)
grep xxx | sort
grep详解
Linux命令 zgrep
使用zgrep命令可以在压缩文件中调用grep按正则表达式来搜索
zgrep -hw
grep xxx ./*.filetype:将path下的全部filetype文件内容进行查询匹配逐行输出=》文件名:匹配列
Linux中sed详解
常见用法:
首先写一个tmpl模板文件然后写一个脚本基于tmpl模板文件替换占位符传参。
sh 脚本.sh 变量参数参数
sed -i /\${tmpl参数占位符} /${变量参数} tmpl复制份
awk中支持C语法, 可以有分支条件判断, 循环语句等, 相当与一个小型编程语言.
脚本命令必须用’'括起来,当匹配规则为字符串和正则表达式的时候需要使用”/…/“符号括起来;而执行命令需要使用{}括起来。
对awk而言,正则表达式是置于两个正斜杠之间、由字符组成的模式。
正则表达式是以/作为开始和结束的标记,表达式语法在两个/中间包裹。
$n~/…/表示某字段匹配该正则表达式:返回true/false
awk默认是按行读取并处理文本,最终按行输出。
awk实现统计功能都是借助awk数组索引下标可为字符串功能进行标识定位。
Linux awk命令详解
linux之awk超详解
linux awk数组操作详细介绍
cat获得文件内容,grep逐行分析提取文件内容并输出,awk解析操作需求内容的每一行。
cat | grep | awk
awk将"作为文本分隔符,然后提取第四列作为sum数组的定位下标并将其对应的数组元素值加一,处理完全部内容后,END最后用for循环逐行输出数组值(一次输出占一行)。
单双引号可以相互包容并原样显示。
注意:实际应用时单包双/双包单,不可单包单,双包双,无意义。
无序:cat XXX.filetype | grep "yyy" | awk -F'"' '{sum[$4]+=1} END {for(k in sum) print k ":" sum[k]}'
有序:(已知:k<=100):cat XXX.filetype | grep "yyy" | awk -F'"' '{sum[$4]+=1} END {for(k=1;k<=100;k++) if (sum[k]>0) print k ":" sum[k]}'
awk -F, '{SUM['$number']=SUM['$number']+1} END {for (i in SUM) print i,SUM[i]} '
awk当中的数组是关联数组,它的索引全是字符串,即便指定为数值也会转化为字符串:arr[1]==arr[“1”]
若数组内使用自定义变量则AWK的数组索引下标直接用"‘’"来声明字符串变量,防止变量为字符串非数值作为下标导致出错。
未使用双引号则默认为数值,反之可为字符串类型(双引号需要在变量最外侧标明)。
'{SUM["'$number'"]=SUM["'$number'"]+$4}'
若报错则说明检索的文本没有对应属性导致SUM[]中下标为空。
echo "123,456,789" | awk -F, '{sum[$1"~"$2"~"$3]++}END{for(i in sum)print i,sum[i]}'
awk 命令默认分隔符为空格或制表符。
插入拼接新字段(直接拼接)
echo "a b c" | awk '{$2=$2" 666" ; print}'
格式化空白(牵一发动全身)
默认格式化后仅字段之间仅保留一个空格。
移除每行的前缀,后缀空白,并将各部分左对齐。
echo "a b c" | awk '{$2=$2 ; print}'
正则表达式是以/作为开始和结束的标记,表达式语法在两个/中间包裹
对awk而言,正则表达式是置于两个正斜杠之间、由字符组成的模式。
awk:取包含inet的行并且!($2匹配/^127/)的$2.
‘true/false{代码块}’:是/否运行代码块。代码块前可加if判断或者去掉if()只留下判断语句决定是否运行代码块。
注意:awk '/xxxyyy/{print}'等效于grep xxxyyy
ifconfig | awk '/inet / && !($2~/^127/){print $2}'
ifconfig | awk 'BEGIN{RS=""}!/^lo/{print$6}'
等价
ifconfig | awk 'BEGIN{RS=""}NR==1{print$6}'
此处也可以在命令行执行。
index($0,"[xxx]"){
print
while( (getline var) > 0 ){
if(var ~ /\[.*\]/){
exit
}
print var
}
}
注意:print==print$0
所有文本操作命令都要在‘{代码块}’中使用
‘true/false{代码块}’:是/否运行代码块。代码块前可加if判断或者去掉if()只留下判断语句决定是否运行代码块。
[xxx]
6?6?6?6?6?6
8?8?8?8?8?8?8?8
9?9?9?9?9?9?9?9?9
[yyy]
9?9?9?9?9?9?9?9?9
8?8?8?8?8?8?8?8
6?6?6?6?6?6
awk -F "?" '!arr[$2]++{print}' test666.txt
awk -F "?" '{arr[$2]++;if(arr[$2]==1)print}' test666.txt
awk '{a[$0]++} END{for(i in a) print i,a[i]}' test666.txt
sort命令
Linux sort命令用于将文本文件内容加以排序。sort可针对文本文件的内容,以行为单位来排序。shell中sort命令有3种执行模式,分别是排序文本,检查文件是否已经排序,合并文件。
数组索引无序输出变为按照数组索引降序输出。
PROCINFO[“sorted_in”]=“@val_num_desc”;
awk '{a[$1]++}END{PROCINFO["sorted_in"]="@val_num_desc";for(i in a)print i,a[i]}' test666.txt
只输出前十个
awk '{a[$1]++}END{PROCINFO["sorted_in"]="@val_num_desc";for(i in a){if(cnt++==10){exit}print i,a[i]}}' test666.txt
key:value
统计相同key下不同value的个数。
点睛之笔:awk数组索引下标排重法(awk自带以逗号为间隔的索引下标表示法)
awk当中的数组是关联数组,它的索引全是字符串,即便指定为数值也会转化为字符串:arr[1]==arr[“1”]
awk -F"|" '!arr[$1,$2]++{cnt[$1]++}END{for(i in cnt)print i,cnt[i]}' test888.txt
BEGIN{FPAT=“[^,]+|\”.*\“”}
awk 'BEGIN{FPAT="[^,]+|\".*\""} {print $1}'
start为$n字段的起始索引(从一开始),length为读取长度。
- substr($n,start,length)//start开始读取length个字符。
- substr($n,start)//start开始读取到最后。
awk -F"," '{print substr($2,1,3)}' test999.txt
在awk语句中,可以使用sub或者gsub进行文本替换,其中sub只是对第一处匹配进行替换,而gsub能够对所有匹配进行替换。
实例演示
源数据格式
1:2:3:4
a: b:c:d
#将每行第一个:替换成-
printf '1:2:3:4\na:b:c:d\n' | awk '{sub(/:/,"-")}1'
1-2:3:4
a-b:c:d
#将每行的:替换成-
printf '1:2:3:4\na:b:c:d\n' | awk '{gsub(/:/,"-")}1'
1-2-3-4
a-b-c-d
实例:去掉空格
awk '{gsub(/ /,"")}1'
注意,这行代码末尾有个‘1’,这个数的作用是表示打印,换成其他非零数字都可以,等同于
awk '{gsub(/ /,"");print $0}'
当涉及*通配符的统计数据出问题时,一般是通配符导致的重复统计问题,需要精确调整下通配符。