AWK
是常用的数据处理工具,内置的变量名称为:
变量名 含义
ARGC 命令行变元个数
ARGV 命令行变元数组
FILENAME 当前输入文件名
FNR 当前文件中的记录号
FS 输入域分隔符,默认为一个空格
RS 输入记录分隔符
NF 当前记录里域个数
NR 到目前为止记录数
OFS 输出域分隔符
ORS 输出记录分隔
$NF 表示最后一列
这里列出几条常用的命令。
编辑
数据格式如下,下面的数据输入到GMT psxy是无法识别这种数字segment的,因此使用awk处理,将segment分隔符修改为>
。
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ head far_xmd_latlon.dat 0 120.52067 36.022747 120.52073 36.022694 1 120.52075 36.022607 120.52083 36.022572 2 120.52083 36.022554 120.52094 36.022519 120.52102 36.022484 120.52108 36.022397 120.52110 36.022345
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ awk '{if(FNR==1){tmp2=$2}if($2==null){$2=$1;$3=$1;$1=">"};tmp2=$2;a[FNR]=$1" "$2; print a[FNR]}' far_xmd_latlon.dat | head > 0 120.52067 36.022747 120.52073 36.022694 > 1 120.52075 36.022607 120.52083 36.022572 > 2 120.52083 36.022554 120.52094 36.022519 120.52102 36.022484 120.52108 36.022397 120.52110 36.022345
|
判断
判断某一列不包含NaN,或者不包含任意其他数字或者字符,替换!/NaN/
。
1
| awk ' !/NaN/ {print $1,$3}' track2.dat >track.dat
|
判断包含某一个数字
1 2
| awk '/101/' file 显示文件file中包含101的匹配行。 awk '/101/,/105/' file
|
按照某一列去掉重复行,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| $ cat hy.txt |head 3.5424793e+02 -6.9635819e+01 6.3286622e+08 6.0882000e+00 -3.9305000e+00 3.5417193e+02 -6.9587913e+01 6.3286622e+08 5.9665000e+00 -3.9174000e+00 3.5409219e+02 -6.9537385e+01 6.3286622e+08 5.8278000e+00 -3.9236000e+00 3.5401280e+02 -6.9486826e+01 6.3286622e+08 5.7029000e+00 -3.9108000e+00 3.5393376e+02 -6.9436234e+01 6.3286622e+08 5.5313000e+00 -3.9370000e+00 3.5385508e+02 -6.9385611e+01 6.3286622e+08 5.3727000e+00 -3.9158000e+00 3.5377474e+02 -6.9333657e+01 6.3286623e+08 5.1118000e+00 -3.9606000e+00 3.5369676e+02 -6.9282970e+01 6.3286623e+08 4.9405000e+00 -3.9307000e+00 3.5361913e+02 -6.9232252e+01 6.3286623e+08 4.7348000e+00 -3.9374000e+00 3.5354184e+02 -6.9181504e+01 6.3286623e+08 4.6018000e+00 -3.9156000e+00
$ awk '!a[$3]++' hy.txt |head 3.5424793e+02 -6.9635819e+01 6.3286622e+08 6.0882000e+00 -3.9305000e+00 3.5377474e+02 -6.9333657e+01 6.3286623e+08 5.1118000e+00 -3.9606000e+00 3.5301023e+02 -6.8825421e+01 6.3286624e+08 3.8921000e+00 -3.9235000e+00 3.5227822e+02 -6.8314285e+01 6.3286625e+08 2.6547000e+00 -3.9175000e+00 3.5157488e+02 -6.7799132e+01 6.3286626e+08 2.0706000e+00 -3.9096000e+00 3.5090018e+02 -6.7281458e+01 6.3286627e+08 2.1666000e+00 -3.9052000e+00 3.5025396e+02 -6.6762768e+01 6.3286628e+08 2.1938000e+00 -3.9343000e+00 3.4963125e+02 -6.6240561e+01 6.3286629e+08 2.6635000e+00 -3.9052000e+00 3.4903220e+02 -6.5716309e+01 6.3286630e+08 3.1479000e+00 -3.9322000e+00 3.4845540e+02 -6.5190147e+01 6.3286631e+08 3.4762000e+00 -3.8902000e+00
|
其他判断
1 2 3 4
| awk '$1 == 5' file awk '$1 == "CT"' file 注意必须带双引号 awk '$1 * $2 >100 ' file awk '$2 >5 && $2<=15' file
|
运算
按照列相加
1 2 3
| $ seq 5 |awk 'BEGIN{sum=0;print "sum:"}{if(NR<=4)printf $1"+";sum+=$1; if(NR==5)printf $1 "="}END{print sum}' sum: 1+2+3+4+5=15
|
简化:
1 2
| $ seq 20 |awk 'BEGIN{sum=0;}{if(NR>1&&NR<=3) sum+=$1;}END{print sum}' 5
|
文件的列相加
1
| awk '{for(i=2;i<=NF;i++)a[i]+=$i;print}END{printf "TOTAL \t";for(j=2;j<=NF;j++)printf a[j]"\t"; print""}'
|
文件的行相加,不含第一列。
1
| awk '{b[NR]=$0; for(i=2;i<=NF;i++)a[NR]+=$i;}END{for(i=1;i<=NR;i++) print b[i]"\t"a[i]}' file
|
文件的行相加,并计算均值。不含第一列。
1
| awk '{b[NR]=$0; for(i=2;i<=NF;i++)a[NR]+=$i;}END{for(i=1;i<=NR;i++) print b[i]"\t"a[i]/(NF-1)}' file
|
文件两列的均方根,可以使用gmt math。但是-C比较容易出错。
1 2
| gmt math -C1 pow5_jizai.txt SQR pow5_jizai_y.txt SQR ADD SQRT = | head gmt math pow5_jizai.txt -C1 SQR pow5_jizai_y.txt SQR ADD SQRT = | head
|
使用awk对任意多个文件计算平均值。具体为有n个文件,具有相同的行列数,然后再文件维度上计算均值。
1
| awk '{a+=$2;c+=$3;d+=$1;b++;}END{for(i=1;i<=FNR;i++)print d/b,a/b,c/b}' pow5_jizai1_x*.txt > pow5_jizai1.txt
|
对两个文件做列的相减:首先对一个文件按照另一个文件的点进行采样,然后使用join
合并两个文件,awk作差。
1 2
| gmt sample1d pow5_jizai1.txt2 -Tpow5_pass.txt2 -Fc > pow5_jizai1.txt3 join pow5_jizai1.txt3 pow5_pass.txt2 | awk ' NR>2 {print $1,$3-$2}'
|
gmt math 计算均值,注意STDIN。如果是文件输入则不需要STDIN。
1 2
| join pow5_jizai1.txt3 pow5_pass.txt2 | awk ' NR>2 {print sqrt(($3-$2)^2)}' | gmt gmtmath STDIN -Sl MEAN = gmt gmtmath ja_t.d -Sl -Ca STD =
|
awk多行变1列,并提取奇数行
1
| awk BEGIN{RS=EOF}'{gsub(/\n/," ");print}' wind_d.txt | awk '{for(i=0;++i<=NF;)a[i]=a[i]?a[i] FS $i:$i}END{for(i=0;i++<NF;)print a[i]}' |awk '(NR%2)!=0 {print $1}'>d.d
|
awk换算角度,-180/180换算到0/360
1 2 3 4 5
| awk '$2<0 {print $1,$2+360}' degree.txt >degree1.txt awk '$2>=0 {print $1,$2}' degree.txt >degree2.txt
cat degree1.txt degree2.txt | sort |
|
awk内使用变量
大概两种办法,分别是'"var"'
和使用-v
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| gmt math -T1/100/0.01 -N2/0 -C1 T SIN = h_f.txt gmt psbasemap `gmt gmtinfo h_f.txt -I0.000001` -JX4i/2i -Bxaf -Byaf -BWSne -K -Xc > test.ps for((i=1;i<=20;i++)); do r=$(($RANDOM%255)) g=$(($RANDOM%255)) b=$(($RANDOM%255)) ((max = $i * 500)) ((min = ($i-1) * 500)) awk 'NR<'"$max"' && NR>'"$min"' {print $1,$2}' h_f.txt >pow5.txt # awk -v m="$max" -v n="$min" 'NR<m && NR>n {print $1,$2}' h_f.txt >pow5.txt2 gmt psxy -R -JX -K pow5.txt -W2.25p,$r/$g/$b -O -i0,1 >> test.ps done
|
- 上面的例子中还包含简单的整数数学运算,语法是
(( c=a+b))
- 浮点预算使用awk
- 使用math 产生二维的时间序列方法
gmt math -T1/100/0.01 -N2/0 -C1 T SIN = h_f.txt
- 不同颜色的绘图叠加方法
r=$(($RANDOM%255))
,加上%255
表示限制在0~255之间随机整数。
应用
从xml文件中批量提取天宫坐标范围
1 2 3 4 5 6 7 8 9 10 11 12
| grep -wf vol.d2 tmp.d > result.d get location of tiangong2 data cat *.xml | grep 'CenterPointLat' | awk -F">" '{print $2}' | awk -F"<" '{print $1}' > ../track.dat cat *.xml | grep 'CenterPointLon' | awk -F">" '{print $2}' | awk -F"<" '{print $1}' > ../track_lon.dat awk '{print $1}' ../track_lon.dat | paste - ../track.dat > ../trc.dat
cat *.xml | grep -e 'Latitude' -e 'Longitude' | awk -F">" '{print $2}' | awk -F"<" '{print $1}' | head
cat *.xml | grep 'Longitude' | awk -F">" '{print $2}' | awk -F"<" '{print $1}' > ../track2_lon.dat cat *.xml | grep 'Latitude' | awk -F">" '{print $2}' | awk -F"<" '{print $1}' > ../track2_lat.dat awk '{print $1}' ../track2_lon.dat | paste - ../track2_lat.dat > ../trc2.dat cat trc2.dat | awk '{if(NR%8 == 0) printf("%s\n>\n", $0); else print $0}' > trc.new
|
批量提取GPS结果中测站名称和坐标信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #!/bin/bash #date:2020-1-18 cd gamit pwd # ls *.xml # touch ../vol.d # touch ../track2_lat.dat touch ../names.txt
for i in `ls *.ios_gamit_detrend.neu` do echo $i # cat $i | grep 'Up stats'| awk -F":" '{print $0}'|awk '{for(i=1;i<13;i=i+1){printf $i" "};printf "\n"}' >> ../vol.d # echo ">" >> ../vol.d cat $i | grep '4-character ID'| awk -F":" '{print $0}' >> ../names.txt # echo ">" >> ../vol.d done
awk -F":" '{print $2}' ../names.txt | paste - ../vol.d > ../vol.d2 awk '{print $3,$1,$2}' ../../figs/trc.dat > ../tmp.d
# awk 'NR==FNR{a[$1]=$0;next}NR>FNR{if($1 in a)print a[$1],a[$2],$1,$1}' ../vol.d2 ../../figs/trc.dat > ../result.d # 匹配两个文件中的相同内容,并输出到一个文件夹。 awk 'NR==FNR{S[$1]=$0;next}NR>FNR{print S[$1],$5,$7,$10,$13}' tmp.d vol.d2 > result.d # 第一列匹配,表示为字母 awk '{if($1 ~ /^[A-Z]+$/) print $0}' result.d > result.d2
|