2017-07-22 84 views
1

我面临一个问题,使用grepawk提取.txt文件中的特定值。 我示出了从.txt文件的摘录如下: “ -如何使用grep和awk提取特定值?

bravais-lattice index  =   2 
lattice parameter (alat) =  10.0000 a.u. 
unit-cell volume   =  250.0000 (a.u.)^3 
number of atoms/cell  =   2 
number of atomic types =   1 
number of electrons  =  28.00 
number of Kohn-Sham states=   18 
kinetic-energy cutoff  =  60.0000 Ry 
charge density cutoff  =  300.0000 Ry 
convergence threshold  =  1.0E-09 
mixing beta    =  0.7000" 

我还定义了一些变量:元素和LAT 我要提取的‘晶胞体积’值,该值等于250.00 。 我尝试以下用grep和awk提取值:

volume=`grep "unit-cell volume" ./latt.10/$ELEMENT.scf.latt_$lat.out | awk '{printf "%15.12f\n",$5}'` 

然而,当我运行bash的文件,我总是得到00.000000结果,而不是250.00正确的值

任何人都可以帮忙吗? 在此先感谢。

回答

3
awk '{printf "%15.12f\n",$5}' 

您要求awk打印出该行的第五个字段($5)。

unit-cell volume   =  250.0000 (a.u.)^3 
1   2    3  4  5 

第五栏是(a.u.)^3,你然后问awk来解释经由%f格式代码的数字。尽管(不是数字),但实际上并不以数字开头,并且当awk被要求将一个非数字字符串作为数字对待时,它会使用0来代替。因此它打印0.

解决方法:改为使用$4。顺便说一句,你可以通过使用awk本身来跳过调用grep来选择行,例如,

awk /^ unit-cell/ {...} 

/^ unit-cell/是在该行的开始处的正则表达式匹配“unit-cell”(带有前导空间)。如果您有其他不想选择的行unit-cell,则根据需要进行调整。

0

由于您正在处理的键值对中键的空间中可能存在可变数量,因此您需要分别调整要处理的每个记录的字段编号($ 4,$ 5等),除非设置了字段分隔符(FS)适当地为FS=" *= *"。然后钥匙将始终在$ 1和$ 2的价值。

然后使用split将值和单位部分彼此分开。

此外,您还可以通过在AWK定义宽松是grepprint动作模式(或条件,/unit-cell volume/):

$ awk 'BEGIN{FS=" *= *"} /unit-cell volume/{split($2,a," +");print a[1]}' file 
250.0000 

解释:

$ awk ' 
BEGIN { FS=" *= *" } # set appropriate field separator 
/unit-cell volume/ { # pattern or condition 
    split($2,a," +") # split value part to value and possible unit parts 
    print a[1]   # output value part 
}' file 
1

你永远需要的grep,当你'使用awk,因为awk可以做grep可以做的任何有用的事情。这听起来像这是你所需要的:

$ awk -F'=' '/unit-cell volume/{printf "%.2f\n",$2}' file 
250.00 

上述工作,因为当FS是=这意味着$2<spaces>250.000 (a.u.)^3当AWK被要求将字符串转换为数字它剥掉后的前导空格和任何数字部分,以便叶250.000被转换为%.2f的数字。

在您发布$5脚本是失败,因为在第5空间分隔的字段:

$1   $2 $3  $4   $5 
<unit-cell> <volume> <=> <250.0000> <(a.u.)^3> 

(a.u.)^3 - 你可以只添加print $5看到。