[英]Separating a number within a column in awk or grep
我正在编写一个脚本,该脚本将处理除第一列之外的所有列中的文件,$ 1。 我要重定向到另一个文件的内容取决于第三列的值,并且我知道该如何区分,但是我想重定向第一列而不是整个第一列的“ id” -number:
不同的输入文件格式:
1452123_s_at 0.45609 1.55e-04 7.85 -2.89 2.657
145243_s_at 0.35709 1.46e-04 7.7 -2.9 2.713
Xl.15267.1.A1_at 0.45609 1.79e-04 7.66 -2.9 2.21
Xl.14257.1.A1_at 0.76509 1.67e-04 7.85 -2.87 2.23
160919_r_at 0.45609 1.83e-04 -7.63 -2.9 -2.888
145916_r_at 0.41869 3.82e-04 -7.56 -2.8 -2.798
162334_r_at 0.51869 2.49e-04 -7.24 -2.93 -2.095
15356_r_at 0.68229 1.79e-04 -7.45 -2.88 -2.5
160365_at 0.68223 3.82e-04 -6.72 -2.98 -1.795
16345_at 0.45623 2.94e-04 -5.99 -2.45 -1.568
26768 0.51869 1.83e-04 7.66 -2.9 2.21
30075 0.67749 1.46e-04 7.45 -2.89 2.34
所需的输出:
1452123 1.55e-04
145243 1.46e-04
15267 1.79e-04
14257 1.67e-04
160919 1.83e-04
145916 3.82e-04
162334 2.49e-04
15356 1.79e-04
160365 3.82e-04
16345 2.94e-04
26768 1.83e-04
30075 1.46e-04
这个数字几乎可以是1到1000万之间的任何数字,整个第一列的结构可能会比此示例稍大一些,但是它将始终在其中包含这个数字。 有什么办法写出足以识别和打印该号码的通用性的东西? 通过使用拆分还是某种方式?
使用哪个程序,awk,grep或sed都没有关系,我只是在寻找最有效的方法。 我对命令行也很陌生,所以请简单解释一下不同的命令! 谢谢
只需使用gsub()
除去非数值,然后打印:
awk 'NF{gsub(/[^0-9]/,"",$1); print $1, $3}' file
它返回:
1452123 1.55e-04
145243 1.46e-04
1526711 1.79e-04
1425711 1.67e-04
160919 1.83e-04
145916 3.82e-04
162334 2.49e-04
15356 1.79e-04
160365 3.82e-04
16345 2.94e-04
26768 1.83e-04
30075 1.46e-04
NF
在执行下面的命令{}
只是如果NF
是真实的,那就是,如果该行不为空。 gsub(/[^0-9]/,"",$1)
用于第一个字段,删除所有不在0-9
范围内的字符。 即,删除所有非数值。 print $1, $3
打印第一个和第三个字段。 我将拆分非数字字符,并选择剩下的最大数字。 以下是我的实现,感谢@fedorqui的NF技巧
NF{n=split($1,a,/[^0-9]+/); v=a[1]; for(i=2; i<=n; i++) { if (v<a[i]) v=a[i]; } print v, $3}
用gensub()的GNU awk:
$ awk 'NF{ print gensub(/([^._]*[._])?([[:digit:]]+).*/,"\\2","",$1), $3 }' file
1452123 1.55e-04
145243 1.46e-04
15267 1.79e-04
14257 1.67e-04
160919 1.83e-04
145916 3.82e-04
162334 2.49e-04
15356 1.79e-04
160365 3.82e-04
16345 2.94e-04
26768 1.83e-04
30075 1.46e-04
我假设模式属于有限集。 这样就可以列出模式了。 为了简化过程,我创建了一个gawk版本:
awk '
NF && ( match($1,/^([0-9]+)((_[rs])?_at)?$/,a) ||
match($1,/^Xl\.([0-9]+)\.1\.A1_at$/,a) ) {
printf("%-12s%-s\n", substr($1, a[1,"start"], a[1,"length"]), $3)
}
' inputfile
第一个match
检查四种模式: <NUM>_s_at
, <NUM>_r_at
, <NUM>_at
, <NUM>
。 最后Xl.<NUM>.1.A1_at
。 然后切断匹配的数字并格式化输出。
输出:
1452123 1.55e-04
145243 1.46e-04
15267 1.79e-04
14257 1.67e-04
160919 1.83e-04
145916 3.82e-04
162334 2.49e-04
15356 1.79e-04
160365 3.82e-04
16345 2.94e-04
26768 1.83e-04
30075 1.46e-04
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.