1. awk注意事项
awk命令格式:awk [选项参数] 'script' var=value file(s)
这里需要特别注意的是,包裹script的是单引号,单引号,单引号!
参考文档Linux awk 命令
2. 删除空行
过滤hostlist.txt中的空行:
1 | cat hostlist.txt |tr -s '\n' |
3. 过滤windows换行符
在windows里编辑好的文件,上传到linux后发现多了^M。以过滤hostlist.txt中的^M为例:
1 | sed -i 's/^M//g' hostlist.txt |
注意,直接复制粘贴上面的命令是无效的。^M的输入方式是 Ctrl + V ,然后 Ctrl + M 。
4. 去除空格
去除test.txt文本中的空格:
1 | cat test.txt | tr -d ' ' |
5. 空格转换行
把test.txt文本中的空格变成换行符。
1 | cat test.txt | tr ' ' '\n' |
6. 查找并插入一行
查找包含- [engineering,subject0]
的文件,- [engineering,subject0]
之后紧接着插入一行- [engineering,subject1]
1 | sed -i 's/- \[engineering,subject0\]/- \[engineering,subject0\]\n- \[engineering,subject1\]/g' * |
7. 大小写字符转换
1 | # 大写转小写 |
PS:对于/etc/hosts
中的主机名和域名,只保留大写或者只保留小写就可以了,因为主机名和域名不区分大小写。
8. 读取某一列
读取第一列,读取最后一列。
1 | echo "www.voidking.com" | awk -F'.' '{print $1}' |
9. 第一列换到最后一列
已知namelist.txt:
1 | haojin 70 80 |
需求:第一列name,在显示时放到最后一列。
1 | cat namelist.txt | awk '{for(i=2;i<=NF;i++)printf("%s ", $i);print $1}' |
10. 循环读取单列文本
已知hostlist.txt为:
1 | www.baidu.com |
需求:批量查询主机名或者主机IP
脚本:
1 | for i in `cat hostlist.txt`;do host $i;done |
11. 文本比较
需求:两个姓名列表,需要对比出两个文件中相同的姓名和不同的姓名。
脚本:
1 | cat file1 > file.txt |
12. 联合查询
使用shell,能否实现类似于SQL的联合查询?必须可以。
已知file1的内容为:
1 | 1 realname |
file2的内容为:
1 | voidking nickname |
需求:根据file1和file2的第二列,把file1和file2合并成一个文件。
1 | 2 voidking nickname |
这个需求使用awk命令来实现。
NR,表示awk开始执行程序后所读取的数据行数。
FNR,与NR功用类似,不同的是awk每打开一个新文件,FNR便从0重新累计。
NR==FNR:用于在读取两个或两个以上的文件时,判断是不是在读取第一个文件。
awk处理多个文件的语法:
1 | awk -F 分隔符 'BEGIN { 初始化 } { 循环执行部分 } END { 结束处理 }' file_list1 file_list2 |
其中BEGIN和END可以省略,-F也可以使用默认,循环执行部分,是按行对文件进行处理的。
脚本:
1 | awk -F " " 'NR==FNR{a[$2]=$0;next}{print a[$2]" "$1}' file1 file2 \ |
由NR=FNR为真时,判断当前读入的是第一个文件file1,执行第一个花括号内的内容。
把file1中每行记录都存入数组a,并使用file1的第2个字段作为下标。
由NR=FNR为假时,判断当前读入了第二个文件file2,执行第二个花括号内的内容。
file2中的每行,根据file2的第2个字段打印数组a中的内容,同时打印file2中的第一列。
13. 求交集
已知file1内容为:
1 | haojin |
file2内容为:
1 | haoshuai 95 93 80 |
需求:file1第一列和file2第一列求交集,显示file2中交集的内容。
1 | awk '{if(NR==FNR){a[$1]=$1}else if($1 in a){print $0}}' file1 file2 |
14. 每两行合成一行
已知ip-port.txt内容为:
1 | 127.0.0.1 |
需求:把ip和对应端口放在同一行。
1 | 127.0.0.1 80 |
脚本:
1 | sed -n "N;s/\n/ /p" ip-port.txt |
15. 计算一列的和
已知fruit.txt内容为:
1 | apple 10 |
第一列是水果名称,第二列是水果数量。
需求1:计算水果的总数。
1 | awk '{sum += $2};END {print sum}' fruit.txt |
需求2:计算存在多少种水果。
1 | cat fruit.txt | awk '{if ($2>0) (sum += 1); else (sum += 0)};END{print sum}' |
16. 根据时间筛选日志
筛选11月10日和11月11日的14:30到18:00的日志
1 | grep -E '1[0,1]/Nov/2022:14:[3,4,5][0-9]|1[0,1]/Nov/2022:1[5-7]|1[0,1]/Nov/2022:18:00' access.log |
grep筛选出的日志,包含18:00:00-18:00:59内的日志。
sed筛选出的日志,只包含第一个匹配上2022:18:00的日志,不包含18:00:00-18:00:59内的日志。