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 命令脚本的执行流程如下:

  1. 当在脚本中使用了 BEGIN 模式,则 BEGIN 中所有的动作都会在读取任何输入行之前执行。
  2. 然后,读入一个输入行并解析成不同的段。
  3. 接下来,每一条指定的非特殊模式都会和输入行进行比较匹配,当匹配成功后,就会执行模式对应的动作。对所有你指定的模式重复此执行该步骤。
  4. 再接下来,对于所有输入行重复执行步骤 2 和 步骤 3。
  5. 当读取并处理完所有输入行后,假如你指定了 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

 

参考1

AWK简明教程【todo】

一些AWK技巧【todo】

阮一峰的教程【todo】

posted @ 2020-01-21 18:31  山竹小果  阅读(241)  评论(0编辑  收藏  举报