一个示例文件myfile.txt
:(Tab分割:“\t”)
head1 | head2 | head3 | head4 | head5 |
---|---|---|---|---|
aaabbb | AAcc | ddCC | ABCD | 10 |
Xaabbb | AYcc | ddCC | AbCD | 22 |
aXaXbb | AAyc | ddZC | ABcD | 35 |
aaXbXX | AAcy | ddCZ | ABCd | 199 |
需求1: 将第1列替换字符中的X
都替换为A
:
awk '{gsub(/X/,"A",$1); print}' myfile.txt
awk '{gsub(/X/,"A",$1); print $0}' myfile.txt
awk -F"\t" '{OFS="\t"}{gsub(/X/,"A",$1); print $0}' myfile.txt
awk '{FS="\t"; OFS="\t"}{gsub(/X/,"A",$1); print $0}' myfile.txt
以上4个命令是等价的。
代码1: 解释命令参数
命令/参数 | 说明 |
---|---|
$0/$1 | awk基本命令,获取所有列;$1: 获取第一列,$2: 获取第二列,$3: … 。 |
gsub | 使用gsub 函数对字符(串)替换。gsub函数参数 gsub(/原字符(串)正则表达式/, 修改字符(串), [指定列,默认所有列]) 。 |
-F /FS | 指定输入的列分割字符,默认是空白字符。示例代码指定Tab “\t”。 注意,如果自定义指定了输入列的分隔符,默认的输出分割符是 一个空格 。如输出列还按tab分割,需要指定 OFS 。 |
OFS | 输出的列分割符。 |
默认print的是所有列,也可使用$0,$1,…指定输出的列。 |
生成结果:
head1 | head2 | head3 | head4 | head5 |
---|---|---|---|---|
aaabbb | AAcc | ddCC | ABCD | 10 |
Aaabbb | AYcc | ddCC | AbCD | 22 |
aAaAbb | AAyc | ddZC | ABcD | 35 |
aaAbAA | AAcy | ddCZ | ABCd | 199 |
例:去除bed文件中的chr字符
awk '{ gsub(/chr/,""); print $1"\t"$2"\t"$3 }' test.bed
也可用sed实现:
sed 's/^chr//g' test.bed
需求2: 格式化输出
代码2:
awk '{printf ("%-30s\t%.10f\t%.4f\n",$1,$5*2,$2/10}') myfile.txt
解释:第一个逗号,
之前为指定的格式,之后为对应格式的值。该示例输出为:原文件第一列【格式为30个字符宽度】,TAB分割,原文件第5列乘2
【格式为保留10位小数】,TAB分割,原文件第2列除以10
【格式为保留4位小数】。
使用int
直接输出整型:
awk '{print int($1)}' myfile.txt
需求3:条件输出if
awk '{if(NR==3){print $0}}' myfile.txt # 输出文件第3行
awk '{if($2>=1){print}}' myfile.txt # 输出文件"第2列值>=1"的行
awk '{if($5=="ABC")print}' myfile.txt # 输出文件第3列字符为"ABC"的行
awk根据条件,也可不使用print
默认输出整行,更简洁:
awk 'NR==3' myfile.txt # 输出文件第3行
awk '$2>=1' myfile.txt # 输出文件"第2列值>=1"的行
awk '$5=="ABC"' myfile.txt # 输出文件第3列字符为"ABC"的行
使用或||
和且&&
条件判断:
awk '$1=="aa" || $3=="bb"' myfile.txt # 第1列为'aa'或第3列'bb'的行
awk '$1!="aa" && $3!="bb"' myfile.txt # 第1列不等于'aa'且第3列不等于'bb'时的行
使用正则匹配:
awk '{if($1~/^AB/)print}' myfile.txt # 输出第1列开头是"AB"的行
awk '{if($1~/AB$/)print}' myfile.txt # 输出第1列末尾是"AB"的行
awk '{if($1~/^AB$/)print}' myfile.txt # 第1列开头和末尾之间是"AB",相当于输出第1列等于"AB"的行
正则匹配:
表达式字符 | 说明 |
---|---|
~ | 匹配表达式 |
!~ | 不匹配表达式 |
[0-9] | 匹配0~9数字 |
+ | 匹配一个或多个 |
? | 匹配0个或1个,比如,匹配第1列是0-99M: $1~/[0-9]?[0-9]M/ |
| | 匹配或,比如,匹配第1列的9M或10M: $1~/9M|10M/ |
awk '{if($6!~/^[0-9]+M$/)print}' myfile.txt # 匹配第6列是"数值M"的格式,例如:100M, 120M, 80M
例:输出fastq文件中的序列行,取余%
:
awk '{if(NR%4==2){print}}' yourfq # 每4行为一组,只输出第2行
用sed同理实现获取指定行:
# 同 sed -n
sed -n '3p' myfile.txt # 输出第三行
需求4:计算某列的和
awk '{sum += $3}END{print sum}' myfile.txt
解释:将第3列累加,END
是指最后执行的命令,即在累加后在最后输出累加的值sum。
需求5:大小写转换
awk '{print toupper($1)}' myfile.txt # 第1列转大写
awk '{print tolower($1)}' myfile.txt # 第1列转小写
需求6:获取子字符串;根据长度获取子字符串
awk '{print substr($1,5,2)}' myfile.txt # (1) 取子字符串
awk '{print substr($1,1,length($1)-3)}' file # (2) 根据字符长度取子字符串
(1) 解释:取第一列,从第5位开始,往后取2个字符。
(2) 解释:取第一列,从第1位开始,往后取第1列总长度-3
个字符。
需求7:根据指定字符对某列进行分割
awk -F "\t" '{OFS="\t"}{split($1, spA, ":"); print spA[2]}' myfile.txt
解释:输入文件以"\t"分割、输出也是"\t"。对第1列按冒号:
分割,定义分割后的列表为spA
,输出spA[2]
即冒号分割的第2列。比如如下文件,":"分割第一列输出的第二个为b1, b2。
head1 | head2 | head3 |
---|---|---|
aa:b1:cc | x1:yy:zz | abcdef |
aa:b2:cc | x2:yy:zz | abcdef |
需求8:传入变量
x1=ABC # 外部定义的变量
awk -v localx1="${x1}" {print localx1"\t"$1} myfile.txt
使用 -v
参数增加变量,如果有多个变量,使用多个-v
即可:
x1=ABC
x2=EFG
awk -v localx1="${x1}" -v2 localx2=${x2} {print $1"\t"localx1"\t"localx2} myfile.txt
需求9:文件格式转置
awk '{i=1; while(i<=NF){col[i]=col[i] $i "\t";i=i+1}}END{i=1;while(i<=NF){print col[i];i=i+1}}' myfile.txt | sed 's/[ \t]*$//g'
需求10:单引号转义
awk '{print "'\''"}' myfile.txt
附1:
附2:sed
一些常用命令
增:
sed '1s/^/str1\t&/' file # file第一行行开始位置增加字符'str1'
sed '1i aAaaAa' test_sed.txt # 第一行之前增加一行(i表示增加指定行前)
sed '$a aAaaAa' test_sed.txt # 末尾行之后增加一行(a表示增加指定行后)
删:
sed '5d' filename # 删除第5行
sed '$d' filename # 删除最后一行
sed '1,5d' filename # 删除从第1行到第5行
sed '/^\s*$/d' filename # 删除空行
注: 连续使用sed,行号是否改变,eg:
sed '2,5d' file | sed '3s/str1/str2/' # 删除第2,5行,替换原始文件的第3行,而不是删除后文件的第3行
改(替换):
sed '1s/str1/str2/' filename # 第一行(1s)第一个str1替换为str2(标准输出)
sed '1s/str1/str2/g' filename # 第一行(1s)所有str1替换为str2(标准输出)
sed 's/str1/str2/' filename # 每行第一个str1替换为str2(标准输出)
sed 's/str1/str2/g' filename # 所有行所有str1替换为str2
sed 's/\t/str2/g' filename # 把\t(Tab空格)换为str2
sed -i '1s/abc/defg/g' filename # 直接替换源文件内容
sed '1s/^/#&/' # 第一行开头加'#' (用于注释命令行)
# 替换中有路径:
sed "2s/\/aaa\/bbb.txt/\/ccc\/ddd.txt/" filename # 替换中含有路径需使用双引号
sed "2s#/aaa/bbb.txt#/ccc/ddd.txt#g" filename # 有包含路径符合"/",使用"#"更方便
sed '2,5s/s1/s2/' filename # 相邻多行替换,从第2到第5行。
# 不相邻的多个行如何替换? sed "1s;3,5s/^/xxx\t/g" filename不对
注:如果替换字符使用变量:变量需要加引号
输出/查:
sed -n '1,3p' filename # 输出第一到第三行内容
sed -n '1p;3p' filename # 输出第一行和第三行内容
sed -n '15,$p' filename # 输出第15行到最后一行的内容
sed -n "1,3p;5p" filename # 输出第一到第三行内容、第5行
未完待续。。。