繁体   English   中英

在awk或grep的列中分隔数字

[英]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

我假设模式属于有限集。 这样就可以列出模式了。 为了简化过程,我创建了一个版本:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM