awk 笔记
cat quora_duplicate_questions.tsv | awk -F "\t" 'BEGIN{a=""} {if ($1=="\""){print a""$0;} else if ($5==""){ a=$4; } else if ($5!="" && $6==""){ a=$4"\t"$5; } else i f (NF >= 6) { print $4"\t"$5"\t"$6;}}' > temp.tsv
awk 指令的通用语法是这样的:
awk 'script' filenames
-F "\t" 以冒号为列分隔符
awk 的特殊模式:BEGIN 和 END
awk ' BEGIN { actions } /pattern/ { actions } /pattern/ { actions } ………. END { actions } ' filenames
- BEGIN 模式:是指 awk 将在读取任何输入行之前立即执行BEGIN 中指定的动作。
- END 模式:是指 awk 将在它正式退出前执行 END中指定的动作。
含有这些特殊模式的 awk 命令脚本的执行流程如下:
- 当在脚本中使用了 BEGIN 模式,则 BEGIN 中所有的动作都会在读取任何输入行之前执行。
- 然后,读入一个输入行并解析成不同的段。
- 接下来,每一条指定的非特殊模式都会和输入行进行比较匹配,当匹配成功后,就会执行模式对应的动作。对所有你指定的模式重复此执行该步骤。
- 再接下来,对于所有输入行重复执行步骤 2 和 步骤 3。
- 当读取并处理完所有输入行后,假如你指定了 END 模式,那么将会执行相应的动作。
匹配
~ 匹配正则
!~ 不匹配正则
== 等于
!= 不等于
打印
test
文件中第二列匹配80开头并以80结束的行
awk '{if($2~/^80$/)print}' test.txt
# $2 ~ /^80$/,~表示匹配后面的表达式, ~ /80/表示包含80,^80表示以80开头,80$表示以80结尾,^80$就是以80开头以80结尾,即等于80。
file文件内容:
123343242
AAAAAAAA
343243243
BBBBBBBB
$awk -v line=$(awk '/(A)+/{a=NR-1;print a}' file) 'NR==line' file
awk '{if($0 == "AAAAAAAA"){print a;}a=$0}'
在匹配到AAAAAAAA后,打印出上一行,也就是 "123343242"
NR是当前行号,表示第几行
使用awk命令获取文本的某一行,某一列的技巧:
1)打印文件的第一列(域) : awk '{print $1}' filename 2)打印文件的前两列(域) : awk '{print $1,$2}' filename 3)打印完第一列,然后打印第二列 : awk '{print $1 $2}' filename 4)打印文本文件的总行数 : awk 'END{print NR}' filename 5)打印文本第一行 :awk 'NR==1{print}' filename 6)打印文本第二行第一列 :sed -n "2, 1p" filename | awk 'print $1
使用awk取某一行数据中的倒数第N列:$(NF-(n-1))
($NF表示倒数第一列,$(NF-1)表示倒数第二列)
linux实现将文本文件每一行中相同第一列对应的其他列进行拼接:
[root@jump-v4 ~]# sort b.txt|uniq 1 34 1 49 2 45 2 48 3 54 3 57 3 89 [root@jump-v4 ~]# sort b.txt|uniq|awk '{a[$1]=(a[$1]" "$2);} END{for(i in a) print i ":"a[i]}' 1: 34 49 2: 45 48 3: 54 57 89 命令解析: 1)首先sort test|uniq实现对test文件的去重,去掉了重复的 1 49,保留不同的行; 2)awk '{a[$1]=(a[$1]" "$2);} END{for(i in a) print i ":"a[i]}' 表示的含义是: 将每一行的第一列作为数组a的key, 第二列作为a的value,同时碰到相同的key,就把其值进行拼接,linux的shell的字符串拼接形式为str = (str “ ” $var), 最后遍历数组a,其中i为数组a的每一个key,a[i]为key对应的值;
不打印第一行:
awk 'NR!=1 {print $1,$2}' test.txt
模糊匹配
(1)模糊匹配
i)使用if
cat test | awk '{if($0~/sss/) {print $0}}' sssbaby sssdde sdsssd
ii)不用if
cat test | awk '$0~/sss/' sssbaby sssdde sdsssd
cat test | awk '/sss/'
sssbaby
sssdde
sdsssd
(2)精确匹配
awk '$1=="sss" {print $0}' filename #输出第一列等于sss的行
(3)反向匹配
awk '$1 !~ /sss/ {print $0}' filename #输出第一列不是sss的行
(4)大小写匹配
awk '/[sS]ss/' filename #匹配含有sss 或是sss的字符串
(5)使用或运算
awk '$0 ~ /(sss|hover)/' filename #查找含有sss或hover字串的行 或awk '{if($0~/sss/ OR $0~/hover/) print $0}' filename
cat test | awk '/[sS]ss|shona/' sssbaby Sss------ shona sssdde sdsssd
AWK简明教程【todo】
一些AWK技巧【todo】
阮一峰的教程【todo】