sed可以对文本内容进行增删改查
主要使用的是改和查;查使用grep,正则表达式使用grep -E更好
awk是文本三剑客中最强大的文本工具;
awk也是按行进行操作;对行操作完之后可以根据指定命令来取列
awk的分隔符:默认为 "空格" 或 "tab键";有多个空格时,会自动压缩成一个进行判断
awk用法:
awk 选项 '模式或者条件{操作}' 文件
-F 指定分隔符;如果是空格,可以不加-f
-v 变量赋值
操作:默认就是打印
awk -F":" '{print $1,$3}' /etc/passwd
$0 表示打印全部
awk常用的内置变量
$n 表示处理行的第几行
NR 表示处理的行的行号
NF 处理当前行的字段个数,$NF就表示最好一个字段
FS 列分隔符,指定文本的分隔符,和F的作用一致;-F:FS=":"
OFS 输出文本的分隔符
RS 指定分隔符为回车
内置变量$n要加$,其他的内置变量不用加$;
更不能用引导也不能用括号,否则会被当成字符串来处理
awk的打印功能
awk '0{print}' 文件A 不打印
awk '1{print}' 文件A 打印全部
awk 'NR==3{print}' 文件A 打印文件A第三行的内容
awk 'NR==2,NR==4{print}' 文件A 打印文件A第二行到第四行的内容
awk 'NR==2;NR==4{print}' 文件A 打印文件A第二行和第四行的内容
奇偶打印:
awk 'NR%2==0{print}' 文件A 打印偶数行
awk 'NR%2==1{print}' 文件A 打印奇数行
awk运算:
awk 'BEGIN{print 10+20}' 计算10+20
awk 'BEGIN{print 3^2}' 计算3的2次方;也可以用**代替^
awk 'BEGIN{print 10.2/4}' 计算小数除法
***面试:awk的内置函数:getline
如果getline左右没有重定向符号 <,> ;或者没有管道符 | 时,awk会先读第一行,但是如果加了getline,会跳过第一行,读取第二行
awk '{getline;print}' 文件A 跳一行打印一行;偶数行打印
awk '{print;getline}' 文件A 打印一行跳一行;奇数行打印
***获取指定文件内容并重定向输出
awk '{getline < "test1.txt"; print > "test2.txt"}' test1.txt
**
ls | awk '{getline ky30;print $0,ky30}'
文本内容过滤打印:
cat /etc/passwd | awk '/^r|bash$/{print}'
BEGIN模式;
awk 'BEGIN{..};{..};END{..}' 文件名
在对文件进行操作之前,会先执行BEGIN{..}模式条件,或者是命令操作
中间的{..}是真正的用于处理文件的命令
END{..}结束语句,一般都是打印执行结果
[root@test1 ~]# awk 'BEGIN{i=0};{i++};END{print i}' /etc/passwd
45
#从零行开始,每行i会自加1;最后打印i的值
-v 变量赋值 #主要用于改变分隔符
fs=":";awk -v FS=$fs -v OFS="+" '{print $1,$3}' /etc/passwd
awk -F: '$4<10{print}' /etc/passwd | head -n 15
以冒号作为分隔符,打印15个第四列小于10的行
awk -F: '!($4<10){print}' /etc/passwd | head -n 15
! 表示取反
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 | sed -n '1,6p'
打印passwd中第三列大于第四列的$3,否则打印$4
awk的精确筛选:
1. > < = 比较数值
2. $n~"字符串" 表示第n个字段包含某个字符
$n!~"字符串" 取反;表示第n个字段不包含某个字符
$n=="字符串" 表示第n个字段就是某个字符
$n!="字符串" 取反;表示第n个字段不是某个字符
$NF 最后一个字段
awk -F: '$7!~"nologin" {print $1,$3}' /etc/passwd
awk -F: '($6~"/home/")&&($7=="/bin/bash") {print $1,$6,$NF}' /etc/passwd
awk -F: '($3!=0)||($4>10) {print $1}' /etc/passwd
awk和tr改变分隔符的比较;tr更直观
[root@test1 ~]# echo a b c d | tr " " ":"
a:b:c:d
[root@test1 ~]# echo a b c d | awk '{OFS=":"; $1=$1;print}'
a:b:c:d
awk结合数组来进行使用
awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a)print i,a[i]}'
***去重