从非列文件中提取数据(在awk中)

时间:2014-01-15 11:28:54

标签: python perl flex awk grep

我正在尝试从非列文件中提取一些特定值。文件格式为

 16O     ADOPTED LEVELS, GAMMAS        1993TI07                  93NP     199902
 16O   L 0.0          0+               STABLE                                   
 16O 2 L ISPIN=0                                                                
 16O 3 L XREF=ABCDEFHIJKLMNOPQ                                                  
 16O   L 6049.4    10  0+              67 PS     5                              
 16O 2 L ISPIN=0                                                                
 16O 3 L XREF=ABCEFIJKMP                                                        
 16O   G 6048.2    10          [E0]                             100             
 16O   L 6129.89   4   3-              18.4 PS   5                              
 16O 2 L ISPIN=0$ MOMM1=+1.668 12 (1989RA17)                                    
 16O 3 L XREF=ABCEFHIJKLNOPQ                                                    
 16O   G 6128.63   4  100      [E3]                                             
 16O 2 G BE3W=13.5 7                                                            

我对序列16O L之后的值感兴趣。对于instanse 0.0,6049.4,6129.89 等。通常,我想从这些文件中提取的值位于序列(Number)(Element)(spaces)L(space)之后。

棘手的是,如果(Element)由一个字母组成,则有3个空格。如果(Element)由两个字母组成,则有2个空格。

是一个示例文件
 10BE    ADOPTED LEVELS, GAMMAS        2004TI06                  04NP     200705
 10BE  L 0.0         0+                1.51E+6 Y 4                              
 10BE2 L ISPIN=1 $ %B-=100                                                      
 10BE3 L XREF=ABDEFIJKLMNOPQSTUVWXYZabceghij                                    
 10BE cL T         from weighted average of T{-1/2}=1.51 Ma 6 (Hofmann et al.,  
 10BE2cL Nucl. Instrum. Meth. Phys. Res. |b 24-25 (1987) 276),                  
 10BE3cL T{-1/2}=1.53 Ma 5% (1993Mi26), and T{-1/2}=1.48 Ma 5% (1993Mi26).      
 10BE  L 3368.03   3 2+                125 FS    12                             
 10BE2 L ISPIN=1 $ %IT=100                                                      
 10BE3 L XREF=ABCDEFIJKLMNOPQRSTUVWXYZabceghij                                  
 10BE cL           B(E2)=52 e{+2} fm{+4} 6 (1987Ra01).                          
 10BE cL E         from {+9}Be(n,|g) (1983Ke11). Other value: 3368.34 keV {I43} 
 10BE2cL (1999Bu26).                                                            
 10BE2 L WIDTHG=3.66E-3 EV 35                                                   
 10BE  G 3367.415  30 100      E2                                               
 10BE2 G WIDTHG=3.66E-3 EV 35$BE2W=8.00 76                                      
 10BE  L 5958.39   5 2+                55 FS     LT                             
 10BE2 L ISPIN=1 $ %IT=100                                                      
 10BE3 L XREF=DFJKLMPRTUWYbeghi                                                 
 10BE cL E         from {+9}Be(n,|g) (1983Ke11). Other value: 5958.3 keV {I3}   
 10BE2cL (1969Al17).                                                            
 10BE  G 2589.999  60 90     GTM1                                               
 10BE  G 5955.9     5 10     LTE2                                               
 10BE  L 13.05E3   10                  290 KEV   130                        A   
 10BE2 L %A GT 0                                                                
 10BE3 L XREF=E                                                                 
 10BE cL E         |G: from {+7}Li({+7}Li,|a+{+6}He) (2001Cu06).

有没有办法使用awk获取这些值? 这类工作还有另一种语言吗?

我用过

awk '/   L/ { print $3 } ' file

表示第一个文件类型(即{3spaces} L)并且它有效。我用了

awk '/  L/ { print $3 } ' file

对于第二个文件类型(即{2spaces} L)并且它给出了奇怪的结果(即它在序列(two spaces)G之后打印值,我无法理解为什么。它唯一可行的方法是使用

awk '/  L / { print $3 } ' file

(即L之后的一个额外空格)。为什么第二种文件类型会发生这种情况? 有没有办法为两种文件类型使用一个代码?

3 个答案:

答案 0 :(得分:1)

您是否正在寻找“160 L”行中的值?如果是这样的话,这应该可以完成这项工作

awk '/16O   L/ { print $3 } ' filename

答案 1 :(得分:1)

使用awk

awk '/[0-9]+[A-Z] {3}L / { print $3 } ' file

awk '$1~/[0-9]+[A-Z]/&&$2=="L"{print $3}' file

使用grep

grep -iPo '\d+[A-Z] {3}L \K[\d.]*' file

答案 2 :(得分:0)

当我看到这个问题时,我认为这将是一个简单的grep线,我错了!我用我的grep线测试至少10次,它没用!终于我发现了原因。 “SH * T!”

示例中的数据:

16O ....

我以为他们是:

160 ....

看到区别? :(

好的,这是行:

grep -Po '^16O {3}L \K[\d.]*' file

输出:

0.0
6049.4
6129.89
6917.1
7116.85
8871.9
9585
9844.5
10356
10957
11080
11096.7
11260
11520
11600
12049
12440
12530
....

如果您希望它采用“一般”方式:

grep -Po '^\d\d[A-Z] {3}L \K[\d.]*'