awk,高效的shell工具

用awk做简单的文件处理

Posted by Xuan on February 18, 2020

Awk 使用技巧汇总

分隔输入文件(-v FS=”分隔符”)或输出文件(-v OFS=”分隔符”)

处理前文件 tmp.txt

  15704 dump10
  14325 dump11
  13178 dump12
  12115 dump13
  11091 dump14
  10057 dump15

awk -v FS="dump" '{print $1 " " $2}' tmp.txt > tmp.out

处理后文件 tmp.out

  15704  10
  14325  11
  13178  12
  12115  13
  11091  14
  10057  15

分隔 输入文件, -F

awk -F '>' '{print $2}' filename

-v 选项, 将外部变量值传递给awk

VAR=10000
echo | awk -v VARIABLE=$VAR '{ print VARIABLE }'

分隔 输出文件, 设置 OFS (Output file separator)

awk -v OFS='\t' '{print $1,$2}' filename
awk 'BEGIN{OFS="\t"} {print $1,$2}' filename

awk 按行合并文件

#每4行合并为一行
awk '{if(NR%4!=0)ORS=" ";else ORS="\n"}1'

RS:Record Separator,记录分隔符
ORS:Output Record Separate,输出当前记录分隔符
FS:Field Separator,字段分隔符
OFS:Out of Field Separator,输出字段分隔符. PS:RS、ORS、FS、OFS的英文解释绝不是这样的,这里只是解释清楚。建议去阅读awk的英文读物,其中解释了缩写的含义

awk 按列合并文件

awk 'NR==FNR{a[$1]=$4;next}{print $1 " " $4 " " a[$1]}' File1.txt File2.txt 

File1的列1 和 File2的列1 相同;按相同的列1合并;

去重复且统计重复条数

sort File_Name |uniq -c 

awk打印倒数列 NF倒数第一列,倒数第二列

awk '{ print $(NF) "," $(NF-1)}' File_Name

awk跳过空行

awk '{if(!NF ){next}}1' file11 实现对文件里面的空行进行跳过操作,并输出结果

awk按列计算(求和,求最值)

# 最大值
awk 'BEGIN {max = 0} {if ($1+0 > max+0) max=$1} END {print "Max=", max}'

# 最小值, pay attention to initialization
awk 'BEGIN {min = 999999} {if ($1+0 < min+0) min=$1} END {print "Min=", min}'

# 求和
awk '{sum+=$1} END {print "Sum = ", sum}' 

# 平均
awk '{sum+=$1} END {print "Average = ", sum/NR}'

awk排除某列输出

将要排除的序列赋值为空;

e.g. 输出除第一列之外的列
awk '{$1=""; print $0}'    文件名
e.g. 输出除第一列第二列之外的列
awk '{$1=""; print $0}'    文件名

awk peak文件处理

计算peak center

awk '{C=$2+int(($3-$2)/2);printf $1"\t%.0f\t%.0f\n",C-1,C;}' \
> ./AI-TAC/AI-TAC_centers.bed

按比例随机分入两个文件 (Train / Validation)

awk 'BEGIN {srand()} {f = FILENAME (rand() <= 0.1 ? ".validation" : ".train");
print > f}' ./AI-TAC/AI-TAC_251bp.tsv

awk 正则匹配

  • 匹配: ~ /正则式/
  • 不匹配: !~ /正则式/

^ 行首 $ 行尾 . 除了换行符以外的任意单个字符

  • 前导字符的零个或多个 .* 所有字符 [] 字符组内的任一字符 [^]对字符组内的每个字符取反(不匹配字符组内的每个字符) ^[^] 非字符组内的字符开头的行 [a-z] 小写字母 [A-Z] 大写字母 [a-Z] 小写和大写字母 [0-9] 数字 < 单词头单词一般以空格或特殊字符做分隔,连续的字符串被当做单词 > 单词尾
awk 'BEGIN{a="100testa";if(a ~ /^100*/){print "ok";}}'

Reference

把文件每隔三行合并成一行(awk之RS、ORS与FS、OFS) awk命令格式和选项