实际中遇到的问题
- 字符串截取函数 substr
#!/usr/bin/awk
#author:zhaoyingnan
#filename:substr.awk
#substr 函数
#echo |awk -f substr.awk
{
#格式化时间格式
#索引1开始
print substr($,,)"-"substr($,,)"-"substr($,,)" "substr($,,)":"substr($,,)":"substr($,,);
printf "%04d-%02d-%02d %02d:%02d:%02d\n",substr($,,),substr($,,),substr($,,),substr($,,),substr($,,),substr($,,);
} - 替换函数 sub 和 gsub
#!/usr/bin/awk -f
#author:zhaoyingnan
#filename:sub.awk
#sub 替换函数
#-- :: current_query => [SELECT * FROM `zhs_user_timeline_147` WHERE and `id`>= limit ]
BEGIN{
FS="[ `>]";
}
{
#删除`
$ == sub(/`/, "", $);
print $;
#sub只会替换模式匹配到的第一个匹配
#相当于vi里面的 %s/apple/banana/
#相当于sed 's/apple/banana/'
}
#!/usr/bin/awk -f
#author:zhaoyingnan
#filename:gsub.awk
#gsub 替换函数
#-- :: current_query => [SELECT * FROM `zhs_user_timeline_147` WHERE and `id`>= limit ]
BEGIN{
FS="[ `>]";
}
{
#删除`
$ == gsub(/`/, "", $);
print $;
#sub会替换模式匹配到的所有的匹配
#相当于vi里面的 %s/apple/banana/g
#相当于sed 's/apple/banana/g'
} - NR和FNR,首先,若是读取一个文件的话,他们是一样的,若是读取多个文件,NR是这几个文件行数的总和,但FNR则在每次读取新的文件时都会从1开始.
- 使用awk 将文件中的时间戳转化为日期,可以使用system调用date
echo |awk '{system("date -d @\""$0"\" \"+%F %T\"")}'
-- :: - 打印指定的字段到最后(使用循环)
ps -ef |grep '/usr/local/php/bin/php excute.php' --color|awk '{ if(NF>=15){ for(i=10;i<=NF;i++){ if(NF==i){ printf "%s\n",$i; }else{ printf "%s ",$i; } } } }'|awk '{ for(i=1;i<=NF;i++){ print $i; } }'|sort -n -t _ -k |wc -l
- 打印出在指定范围内不存在的行(使用数组)
#!/bin/awk -f
#author:zhaoyingnan
BEGIN{
for(i=;i<=;i++)
{
num[i]=i;
}
}
{
exists[$]=$;
}
END{
for(j in num)
{
if(num[j] in exists)
{
}
else
{
print "db_community=>zhs_user_timeline_"num[j]" is end";
}
}
} - 指定多个分隔符时,最好不要偷懒,需要写成 -F "[.......]"
#!/bin/bash
#批量修改文件
#oldsix-.html -> linux-.HTML
for file in `ls`
do
mv $file `echo $file|awk -F "[-.]" '{printf "%s%s%s","linux-",$2,"."toupper($3)}'`
done
下面不用看
#!/usr/bin/awk -f
# 在系统提示下输入脚本
# 本文为awk笔记
#
# ********************************************************************************************************************************************
# awk 命令格式
# awk [options] 'pattern{action}' [var1=value1 var2=value2] files
# 模式部分和操作部分都是可选的.如果没有指定模式,则操作会应用到全部的记录[zyn1];如果没有指定操作部分,则会输出匹配的全部记录.[zyn2]
# 模式部分和操作部分都是可以出现多次.
#
# ********************************************************************************************************************************************
#
# options 选项部分
# -f 从脚本中读取awk命令
# -F 指定多个字段分割符[zyn3]
# -v 赋值一个用户定义变量[zyn4]
#
# ********************************************************************************************************************************************
#
# pattern 模式部分
# 由某种表达式组成的语句,模式不能被括在{}内:
# BEGIN{} 指定在第一条输入记录被处理之前发生的动作;
# END{} 指定在最后一条输入记录之后发生的动作;
# 判别条件真伪的表达式:~表示匹配,!~表示不匹配;字符串或数字比较;关系运算;[zyn5]
# /模式1/,/模式2/ 指定一个行的范围.[zyn6]
#
# ********************************************************************************************************************************************
#
# action 操作部分
# 由{}括起的一条或多条语句组成,语句间用;或者换行符分割,默认操作是打印所有表达式结果为真的文本行:
# 格式化输出;
# 变量或数组操作;
# 内置函数;
# 控制流命令
#
# ********************************************************************************************************************************************
#
# 脚本文件格式
# 如果同一行上有多个语句或操作,必须用;隔开;如果每条语句都在不同的行上,可以不用加;
# 如果操作跟在某个模式后面,它的{就必须与该模式在同一行[zyn2],[zyn5],[zyn6],[zyn7]
# 注释要一#开头
#
# ********************************************************************************************************************************************
#
# 正则表达式元字符
# ^在串首匹配 $在串尾匹配 .匹配任意单个字符 *匹配零个或多个前一个字符
# +匹配一个或多个前一个字符 ?匹配零个或一个前一个字符 []匹配指定字符串组
# [^]匹配任意一个不在指定字符串组 |匹配两者之一 ()+匹配一个或多个组合
# &用在代替字符串中,代表查找串中匹配到的内容[zyn9]
#
# ********************************************************************************************************************************************
#
# 正则表达式POSIX字符类
# [:alnum:]文字数字字符 [:alpha:]文字字符 [:digit:]数字字符 [:graph:]非空字符(包括空格)
# [:punct:]标点符号 [:lower:]小写字符 [:upper:]大写字符 [:cntrl:]控制字符
# [:space:]所有空白字符(空格,新行,制表符) [:xdigit:]十六进制数字 [:blank:]空格和制表符
#
# ********************************************************************************************************************************************
#
# 关系运算符:<,<=,>,>=,==,!=
# ~,!~在正则中的匹配,不匹配
# 条件表达式:?:三元运算符,if else
# 逻辑运算符:||,&&,!
# 算数运算符:+,-,*,/,%,^(求冥),&(求余),++(一元加),--(一元减),赋值=,+=,-=,*=,/=,%=,^=,**=
# 范围:/../,/../
#
# ********************************************************************************************************************************************
#
# 影响流程控制的语句
# 除了if,while,for,do之外,还有break,continue,next
# 在一个循环中的两个影响流程控制的break以及continue:break是退出循环,continue是终止当前的循环,并开始下一次的循环;
# next:可以连续从文件读取内容,忽略脚本的其他操作直到文件被读完[zyn10],[zyn11]
# exit:exit使主输入循环退出控制,执行END{}中的操作,如果没有END{},或者换行符分割是在END{}中应用了exit,则终止脚本执行.
#
# ********************************************************************************************************************************************
# getline函数,注意它不用加上()
# getline函数用于从输入中读取下一行,它不仅能读取正常的数据流,而且能处理来自文件和管道的输入[zyn12][zyn13]
# getline函数可能的返回值为: 如果能够读取一行. 如果到了文件末尾.- 如果遇到错误
# getline函数读取新的行之后,会将其赋值给$,并且将其分解成字段,同时设置了系统变量NF和NR以及FNR,如若不想改变$,可将其赋值给别的变量,但是系统变量还是会被设置的
# close()函数用于关闭打开的文件和管道
# 在不同的系统中,能打开的管道的数量是不同的,但是是都有一定数量的限制的;
# 关闭一个管道使得你可以运行同一个命令两次;[zyn13]
# 关闭一个输出管道是必要的[zyn14]
# ********************************************************************************************************************************************
#
#
# [zyn1]
# awk -f awk.awk lianxi.txt
#BEGIN{printf "%s\n","没有模式部分";}
#{
# print $;
#}
#END{}
#
#
# [zyn2]
#BEGIN{printf "%s\n","没有操作部分";}
#$~/^$/{
# print $;
#}
#END{}
#
#
# [zyn3]
# echo '1,2,3,4,5,6'|awk -f awk.awk
#BEGIN{FS=",";OFS="-";}
#{
# print $,$,$,$,$;
#}
#END{}
#
#
# [zyn4]
# -v awk -vname=$USER -f awk.awk rizhi.txt 使用的是系统变量
# awk -vname="haha" -f awk.awk rizhi.txt 自定义变量
# awk -vname="haha" -vhome="gg" -f a.awk rizhi.txt 多个变量
# awk -vname="zhaoyingnan" -vhome="hebei" -f awk.awk lianxi.txt
#BEGIN{OFS="-";}
#{}
#END{printf "name:%s,home:%s",name,home;}
#
#
# [zyn5]
# 在每个非空的行的结尾追加字符,且保留源文件的空行
# awk -f awk.awk lianxi_5.txt
#BEGIN{}
#$~/^$/{
# print $;
#}
#$!~/^$/{
# print $"<br/>";
#}
#END{}
#
#
# [zyn6]
#BEGIN{PS="\"";OFS="\T";}
#/<h4>/,/<\/h4>/{
# print $;
# print $;
#}
#END{}
#
#
# [zyn7]
# awk -f awk.awk lianxi6.txt
#BEGIN{FS="\t"}
#/^[A]/{
# print $;
#}
#$~/^[rR]/{
# print $;
# }
#$~/^[^rR][^].*/{
# print $;
# }
#END{}
#
#
# [zyn8] fail
# POSIX字符类 需要开启posix支持
# awk --posix -f awk.awk lianxi6.txt
#BEGIN{}
#$~/^[rRaAbB][[:digit:]].*/{
# print $;
# }
#END{}
#
#
# [zyn9] fail
# &使用
#BEGIN{}
#/^[rR][sS]/{
# print $;
#}
#END{}
#
#
# [zyn10]
# 将国家名称顺序修改
# awk -f awk.awk country.txt
#BEGIN{
# printf "%s\t\t%s\t\t%s\t\t\n","英文全称","英文缩写","中文全称";
#}
#{
# if(NR%!=)
# printf "%s\t\t",$;
# else
# printf "%s\n",$;
#}
#END{}
#
#
# [zyn10]
# 世界各中英文对照表
# awk -f awk.awk country_format.txt country_yingwen.txt
#BEGIN{FS=",";OFS="\t";}
#FILENAME=="country_format.txt"{
# split($,entry,",");
# country[entry[]]=entry[];
# next
## print entry[],entry[],entry[];
#}
#/[A-Z][a-z]+/{
# for(i=;i<=NF;i++)
# {
# if($i in country)
# {
# $i=country[$i]"("$i")";
# }
# }
# print $,$,$;
#}
#END{}
#
#
# [zyn11]
# 星期月份对照表
# awk -f awk.awk week_and_month_mix.txt week_and_month_desc.txt
#BEGIN{FS=",";}
#FILENAME=="week_and_month_mix.txt"{
##week_and_month_mix/txt文件的每一行都会执行action的操作
# split($,swap,",");
# week[swap[]]=swap[]" "swap[];
# next
#}
#/[A-Z][a-z]+[.]?/{
##只有从不同文件输入内容的时候才会执行
# for(i=;i<=NF;i++)
# {
# if($i in week)
# {
# $i=$i"("week[$i]")";
# }
# }
# print $;
#}
#END{}
#
#
# [zyn12]
# 测试getline执行流程
#
#BEGIN{}
#/^(AB).*/{
# print $;
# while(getline>)
# {
# if($~/^(KL).*/)
# {
# a=$;
# print a;
# }
# else
# break
# }
#}
#END{}
#
#
# [zyn13]
# getline 从管道读入输入
#BEGIN{}
#{
# "whoami"|getline me;
# close("whoami");#这里必须将这个管道关掉,否则下面的不能用哟
# "whoami"|getline my;
# "pwd"|getline path;
# print $,me,my,path;
#}
#END{}
#
#
# [zyn14]
# close()关闭一个输出管道
#BEGIN{filename="sort7.txt"}
#{
# print $|"sort > sort7.txt"
#}
#filename=="sort7.txt"{
# while((getline < filename)>)
# {
# print $;
# }
#}
#END{}
#
#
# ********************************************************************************************************************************************
# awk中的函数
# gsub(pattern,replace,subject)
# 在字符串subject用replace替换和正则表达式pattern相匹配的所有字符串,返回被替换的个数,若没有提供subject则默认为$
# sub(pattern,replace,subject)
# 和gsub相同,不同的是,gsub是所有位置的替换,sub只替换第一个位置哟
# awk -f awk.awk 10_zhaoyingnan.log
#BEGIN{FS="\"";}
#{
# sub(/\//,"_",$16);
# gsub(/\//,"_",$16);
# gsub(/\.[jJ][pP][Gg]/,".jpg",$);
# print $
#}
#END{}
#
#
# index(subject,search)
# 返回子串search在subject中的位置,若没有则返回0
# substr(subject,starposion,length)
# 返回subject中从startposion开启,最大长度为length的子串,若没给出length,则返回从startposion开始到结束的子串
# awk -f awk.awk 10_zhaoyingnan.log
#BEGIN{FS="\""}
#{
# print $,index($,"pai");
# print $,index($,"suipai");
# print $,substr($,index($,"c180"));
#}
#END{}
#
#
# tolower(subject)将字符串subject中所有的大写字符转换为小写,返回新的字符串
# toupper(subject)将字符串subject中所有的小写字符转换为大写,返回新的字符串
# awk -f awk.awk 10_zhaoyingnan.log
#BEGIN{FS="\""}
#{
# print $,tolower($),toupper($);
#}
#END{}
#
#
# length(subject) 返回subject的长度,若没有指定subject,则返回$0的长度
#
#BEGIN{FS="\""}
#{
# print length,length($),"中文长度"length("中文");
#}
#
#
# match(subject,pattern)
# 如果正则表达式pattern在subject中出现,则返回出现的启始位置,并设置RSTART为该位置,设置RLENGTH为匹配字符串的字符数,否则返回0,并设置RSTART为0,RLENGTH为-;
# echo "APPLE,PALNE"|awk -f awk.awk
#BEGIN{FS=","}
#{
# for(i=;i<=NF;i++)
# print $i,match($i,/[A-Z]+/),RSTART,RLENGTH;
#}
#END{}
#
#
# split(subject,array,decollator)
# 使用分隔符decollator将subject分解到array数组中,返回元素的个数,如没有给出decollator则使用FS
#BEGIN{FS=","}
#{
# split($,array)
# for(i in array)
# print array[i]
#}
#END{}
测试用到的文件
sed -n '/^#\s*awk.*\.[tl]/p' awk.awk |uniq
# awk -f awk.awk lianxi.txt
# awk -vname="haha" -f awk.awk rizhi.txt 自定义变量
# awk -vname="haha" -vhome="gg" -f a.awk rizhi.txt 多个变量
# awk -vname="zhaoyingnan" -vhome="hebei" -f awk.awk lianxi.txt
# awk -f awk.awk lianxi_5.txt
# awk -f awk.awk lianxi6.txt
# awk --posix -f awk.awk lianxi6.txt
# awk -f awk.awk country.txt
# awk -f awk.awk country_format.txt country_yingwen.txt
# awk -f awk.awk week_and_month_mix.txt week_and_month_desc.txt
# awk -f awk.awk 10_zhaoyingnan.log