awk
变量名
ARGC 命令行变元个数
ARGV 命令行变元数组
FILENAME 当前输入文件名
FNR 当前文件中的记录号
NF 当前记录里域个数
$NF 最后的域
NR 到目前为止记录数
$NR 行号
FS 输入域分隔符,默认为一个空格
OFS 输出域分隔符
RS 输入记录分隔符
ORS 输出记录分隔符
命令选项
-F 指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F :(即FS)
-v 赋值一个用户定义变量。
环境变量
$n 当前记录的第n个字段,字段间由FS分隔。
$0 完整的输入记录。
内建函数
- sub 第一次匹配替换
{ sub(/test/, "mytest")}
{ sub(/test/, "mytest"); $1}
- gsub 整个文件中进行匹配
- index 返回子字符串第一次被匹配的位置,偏移量从位置1开始
{ print index("mytest", "test") }
- length 函数返回记录的字符数。
awk '{ print length( "test" ) }'
awk '{ print length }' testfile
- substr 函数返回从位置1开始的子字符串,如果指定长度超过实际长度,就返回整个字符串
awk '{ print substr( "hello world", 7,11 ) }' # 返回world
- match 函数返回在字符串中正则表达式位置的索引,如果找不到指定的正则表达式则返回0。
$ awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'
- toupper 和tolower 函数可用于字符串大小间的转换
- split 函数可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割。
awk '{ split( "20:18:00", time, ":" ); print time[2] }'
脚本
- 显示文件file中包含101的匹配行
awk '/101/' file
- 第2个参数包含connect
awk '$6~/connect/' file
- 通过设置输入分隔符(FS=”[: \t|]”)修改输入分隔符。
awk 'BEGIN { FS="[: \t|]" } {print $1,$2,$3}' file
- 格式化输出
格式化输出:
netstat -anp|awk '{printf "%-8s %-8s %-10s\n",$1,$2,$3}'
- RS使用
# 1.txt
g 1 234
gd 343 546 6577 32
awk 'BEGIN{RS=" "}{print $1}' 1.txt
g
1
234
343
546
6577
32
awk 'BEGIN{RS="\n"}{print $1}' 1.txt
g
gd
- 添加信息
awk可以用双引号来添加信息
awk '{print "hello"$NF}'
- 计算/home目录下,普通文件的大小,使用KB作为单位
ls -l|awk 'BEGIN{sum=0} /^-/{sum+=$5} END{print "total size is",sum/1024,"KB"}'
- 统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少
netstat -anp |awk '$6~/LISTEN|CONNECT/{sum[$6]++} END{for (i in sum) printf "%-10s %-8s %-3s", i, " ", sum[i]}'
- 假如把2列和3列的值作为新的第5列,第5列的平均值为avg5,求第5列中大于avg5的行数。
## 1.txt
3 5 6 7
2 3 1 0
4 5 6 9
2 3 4 4
2 2 1 0
4 5 0 9
cat 1.txt |awk "{a[NR]=$2+$3;sum+=a[NR];print $0,a[NR]}END{avg=sum/NR;for (i in a){if (avg < a[i]) z++};print z}"
grep
参数
-o 只显示匹配内容,
-v 取反
-E 支持正则,egrep
-n 显示行号
-i 忽略大小写
-w 精确匹配(匹配整词)
-e 多个模式
—color=auto 高亮
-m num:当匹配内容的行数达到num行后,grep停止搜索,并输出停止前搜索到的匹配内容
-q:安静模式,不会有任何输出内容,查找到匹配内容会返回0,未查找到匹配内容就返回非0
-n:输出匹配内容的同时输出其所在行号。
脚本
- 正则
### 1.txt
g
gd
go
god
good
goood
gooo
gooood
godo
godddo
egrep "go+d" 1.txt
god
good
goood
gooood
godo
godddo
egrep "go*d" 1.txt
gd
god
good
goood
gooood
godo
godddo
egrep "go?d" 1.txt
gd
god
godo
godddo
egrep "go.d" 1.txt
good
godddo
egrep "god|good" 1.txt
god
good
godo
godddo
egrep "g(o|oo)d" 1.txt
god
good
godo
godddo
- 记录文件中单词的重复数量
cat passwd |egrep -o "[a-zA-Z]+"|sort|uniq -c|sort -nr|tr -s " "
sed
模式
- a :新增, a 的后面可以接字串,如 /123/a 456,在它之后添加一行
- c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
- d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
- i :插入, i 的后面可以接字串,如 /123/a 456,在它之前添加一行
- p :列印,1p 打印第一行 1,5p打印1到5行
- s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!
vim中修改要加%
:s/hello/hi/g%
添加使用&,在后面添加
sed -i s/hello/& hi/
在前面添加
sed -i s/hello/hi &/
查询文本方式
x x为行号
x,y 表示行号从x到y
/pattern 查询包含模式的行
/pattern /pattern 查询包含两个模式的行
pattern/,x 在给定行号上查询包含模式的行
x,/pattern/ 通过行号和模式查询匹配的行
x,y! 查询不包含指定行号x和y的行
选项
-n :只打印模式匹配的行,一般与模式p配合
-e :直接在命令行模式上进行sed动作编辑,此为默认选项
-f :将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作
-i :直接修改文件内容
-r 支持扩展表达式,正则表达式要用括号括起来。
$ echo hello123|sed -r 's#([a-z]*)([0-9]{3})#\2\1#g'
123hello
正则
\{m,n\} 匹配其前面的字符至少m次,至多n次
\{m,\} 匹配其前面的字符至少m次
\{m\} 精确匹配前面的m次\{0,n\}:0到n次
[] 匹配指定范围内的任意单个字符
[^] 匹配指定范围外的任意单个字符
脚本
- 替换后缀
for i in `ls $(pwd)`:
do
c=`echo $i|sed -r "s#([a-z]{10}).*#\1#g"`
mv $(pwd)/$c* $(pwd)/$(c)oldgirl.HTML
done
- 查找文件夹中文件及其子文件夹
file=$(pwd)/test
for i in `find $file -name "*2018"`
do
for n in `ls $i`:
do
sed -i "s/test/daba/g" $i/$n
done
done
常用文本处理方式
find
-name filename
-perm 权限
-user 用户
-group 组
-maxdepth 1 只找第一级目录
-type f 只找文件类型
-mtime +30 30天以前的
-exec cp {} /tmp/ \ 拷贝到/tmp下,也可以使用 |xargs(使用在删除的场景)
-size +200M 大于200M的文件
sort
-n 依照数值大小排序
-r 按照相反的顺序来排序
-u 去除重复行
uniq
-i 忽略大小写
-c 进行计数
-u 只显示唯一的行
cut
-d 接分割字符
-f 依据-d的分隔符将信息分段,-f取出第几段
-c 以字符单位取出固定字符区间
# 找到第三到最后一段
cut -d ':' -f 3-
# 找到3和5段
cut -d ':' -f 3,5
# 找到3到5段
cut -d ':' -f 3:5
wc
-l 仅取出列,统计行数
-w 仅取出多少字,统计单词出现次数
-m 多少字符,统计文件的字节数
tr
-s 去除重复序列,压缩成一个
-d 删除字符
-c 使用字符替代
脚本
- 记录文件中单词的重复数量
cat passwd |egrep -o "[a-zA-Z]+"|sort|uniq -c|sort -nr|tr -s " "