sed 文本的内容进行增删改查
改 增 查没有grep好用 正则表达式grep -E
awk 文本三剑客之一,是功能最强大的文本工具。
awk 也是按行来进行操作的,对行操作完之后,可以根据指定命令来对行取列。
awk的分隔符:它的默认分隔符是空格或者tab键,多个空格它会自动压缩成一个。
1 2 3 4 都算是一个空格
awk也支持编程语言。
用法:
awk的格式:
awk 选项 '模式或者条件 (操作)'文件
-f 指定分隔符,如果是空格,不需要加f
-v 变量赋值。
操作:默认就是打印
打印多个列:
awk常用的内置变量:
$0:打印所有内容
$n:处理行的第几列
NR:处理行的行号
NF:处理当前行的字段个数,$NF就表示最后一个字段
FS:列分隔符,指定文本的分隔符,和F的作用一致。-F:FS=":"
OFS:输出文本的分隔符
RS:行分割符,指定分隔符为回车。
内置变量$n要加$,其他的内置变量不用加$,更不能用引号,也不能用括号,否则会被当成字符串来处理。
awk的打印功能
awk '{print}' test.txt
print前面的值默认为1,打印所有,'0{print}'不打印
只打印行号
awk '{print NR}' test.txt
awk '{print NR,$0}' test.txt
既打印行号,又打印内容
指定行号打印:
vim test.txt
awk 'NR==3{print}' test.txt 只打印第三行
awk 'NR==2,NR==4{print}' test.txt 打印第二行到第四行
awk 'NR==2;NR==4{print}' test.txt 打印第二行和第四行
奇偶打印
awk 'NR%2==0{print}' test.txt 偶数行
awk 'NR%2==1{print}' test.txt 打印奇数行
awk运算
awk 'BEGIN{print 10+20}'
awk 'BEGIN{print 10*20}'
awk 'BEGIN{print 10/20}'
awk 'BEGIN{print 3**2}' 它也默认支持幂运算
3**2=3^2=9
awk自带支持小数运算
awk 'BEGIN{print 10.2/20.3}'
awk ‘{print $3}’ test.txt 只打印第三列
awk '(print $3,$4') test.txt 打印第三列和第四列
awk的内置函数(难点,面试会问)
getline
1、如果getline左右两面没有重定向符号(<,>),或者没有(|)时,awk会先读第一行,但是如果加了getline,它会跳过第一行,读取第二行
awk '{getline;print}' test.txt
2、如果两边有重定向或者管道符,getline作用于定向输入文件
awk '{getline ky30;print$0,ky30;}'(也可以直接cat test1 > test2)
| 管道符的作用
ls | awk '{getline ky30;print $0,ky30;}'
getline ky30 自定义变量
ls输出的结果传给ky30
打印ls命令的输出结果。
如果没有结果,打印空,不做任何操作。
文本内容过滤打印
例:以root为开头。
awk '/^root/{print}' /etc/passwd
以bash为结尾
awk '/bash${print}/' /etc/passwd
不标开头或者结尾
awk '/x/{print}' /etc/passwd
所有包含x的行都打印出来了
BEGIN模式:
awk 'BEGIN{..};{..};END{..}' 文件
例:获取文件有多少行
awk 'BEGIN{i=0};{i++};END{print i}' /etc/passwd
在对文件进行操作之前,会先执行BEGIN(..)模式条件,或是命令操作
中间的(..)是真正的用于处理文件的命令
END(..)结束语句,一般都是打印执行结果
-v 变量赋值(了解即可)
指的是改变分隔符
fs=":";awk -v FS=$fs -v OFS="+" '{print $1,$3}' /etc/passwd(1-3列中间的分隔符变为+号)
简写:
awk -v FS=":" FS=$fs -v OFS="+" '{print $1,$3}' /etc/passwd
RS:指定分隔符为回车(了解即可)
echo $PATH | awk -v RS=":" '{print $1}'
只打印这一列比RS少了一个空行
awk条件判断打印
例:
awk -F: '$3>10{print}' /etc/passwd | head -n 15
只取十五行,第三列大于10的15行
题1:取所有第四列小于10的行
awk -F: '$4<10{print}' /etc/passwd | head -n 15
大于10:awk -F: '!($4<10){print}' /etc/passwd | head -n 15
awk支持条件判断语句 if
awk -F: '{if ($3=10) {print}}' /etc/passwd
awk -F: '{if ($3>10) {print}}' /etc/passwd
awk条件判断打印:
三元表达式:类似于Java(面试会问)
awk '(条件表达式) ?(A表达式或者值):(B的表达式或者值)'
?就是if
:就是else
例:awk -F:'{i=($3>$4)?$3:$4;{print i}}' /etc/passwd
如果i的值满足第三列大于第四列,就先打印第三列,不满足就打印第四列
更直观一点,打印1-6行看一下
awk的精确筛选:
$3>$4
<
=(以上的只能比较数值大小)
$n~"字符串":表示第n个字段包含某个字符
$n!~"字符串":表示第n个字段不包含某个字符 (比较字符串前面加~号)
$n=="字符串":表示第n个字段就是某个字符
$n!="字符串":表示第n个字段不是某个字符
$NF:表示最后一个字段
例:head -n 2 /etc/passwd | awk -F: '{print $NF}'
题1:第七列包含bash的,但是只打印它的第一列和最后一列
awk -F: '$7~"bash" {print $1,$NF}' /etc/passwd
题2:第七个字段不是nologin,打印第一个字段和第三个字段。
awk -F:'$7!~"nologin" {print $1,$3}' /etc/passwd
逻辑关系
|| 逻辑或
&& 逻辑且
多个条件判断用()括起来
题1:指定第六个组电压表为/home/dn 而且 第七个字段的 /bin/bash
awk -F: '($6=="/home/dn")&&($7=="/bin/bash"){print $1,$NF}' /etc/passwd
变1:把且变为或
awk -F: '($6=="/home/dn")||($7=="/bin/bash"){print $1,$NF}' /etc/passwd
主要用于两个条件表达式之间,不能用于打印,打印会出现歧义
题2:所有第三列不是0的,或者第四列大于10的结果,只打印第一列
awk -F: '($3!=0)||($4>10) {print $1}' /etc/passwd
awk和tr比较改变分隔符(了解即可)
echo a b c d | tr " " ";" 字符集1改为字符集2
echo a b c d | awk '{OFS=":"; $1=$1;print}'
推荐使用tr
重难点:awk结合数组来进行使用
在awk当中,怎么样来定义数组
awk 'BEGIN{a[0]=10}'