Bash简单的字符串解析

时间:2012-01-06 16:16:19

标签: bash sed awk

鉴于此格式:

DISKGROUP NAME    GB ALLOCATED         GB USED         GB FREE       USABLE GB PCT USED STATUS                          
-------------- --------------- --------------- --------------- --------------- -------- --------------------            
DISK_1             1,117.40          390.48          726.92          223.78    34.95 MOUNTED                         
DISK_2         1,117.40           65.97        1,051.43          386.04     5.90 MOUNTED   

使用单个bash命令如何可靠地从GB FREE获取值?字段之间的空格数可以非常基于字段大小,因此我无法指定具有剪切的静态空格数。有没有办法使用空格作为分隔符,但空格的数量是可变大小?

感谢您的任何想法

2 个答案:

答案 0 :(得分:7)

您可以使用awk

awk 'BEGIN {print "GB FREE\n--------"} NR>2{print $4}' INPUT_FILE

说明:

  1. 我们使用awk's BEGIN语句打印标题GB FREE and -------。这是因为输入文件中的标题在标题中有空格。这可以抛弃awk脚本。
  2. 其次,我们使用awk's内置变量NR来存储行号。由于我们不希望打印第1行和第2行,因此我们保持NR>2的条件。这样awk将跳过前两行并从第3行开始打印。
  3. 默认情况下,在awk中,分隔符或字段分隔符是空格(一个或多个)。由于您的文件有,我们不需要设置FS内置变量。由空格分隔的每个字段都成为一列,可以使用$column number进行访问。由于您希望GB FREE列为4,我们会print $4
  4. 要保留更多条件,例如只打印column 1 DISK_2 NR>2 && $1~/DISK_2/的行,我们会添加另一个模式语句。使用column 1可确保我们不会打印第1行和第2行,并查找DISK_2中包含column 4的行,并打印这些行的awk 'NR>2{print $4}' INPUT_FILE 行。
  5. 注意:如果您不关心标题部分,可以将此单行程缩短为以下(根据您的要求):

    awk 'NR>2 && $1~/DISK_2/{print $4}' INPUT_FILE
    

    [jaypal:~/Temp] cat file
    DISKGROUP NAME    GB ALLOCATED         GB USED         GB FREE       USABLE GB PCT USED STATUS                          
    -------------- --------------- --------------- --------------- --------------- -------- --------------------            
    DISK_1             1,117.40          390.48          726.92          223.78    34.95 MOUNTED                         
    DISK_2         1,117.40           65.97        1,051.43          386.04     5.90 MOUNTED   
    
    [jaypal:~/Temp] awk 'BEGIN {print "GB FREE\n--------"} NR>2{print $4}' file
    GB FREE
    --------
    726.92
    1,051.43
    

    测试:

    [jaypal:~/Temp] awk 'BEGIN {print "GB FREE\n--------"} NR>2 && $1~/DISK_2/{print $4}' file
    GB FREE
    --------
    1,051.43
    

    添加评论中所述的过滤器:

    {{1}}

答案 1 :(得分:1)

这可能对您有用:

sed '1,2d;s/\(\S*\s*\)\{3\}\(\S*\).*/\2/' file

如上标题:

sed '1,2c\ GB FREE\n--------'$'\n'';s/\(\S*\s*\)\{3\}\(\S*\).*/\2/' file

或仅限DISK_2

sed '/^DISC_2/s/\(\S*\s*\)\{3\}\(\S*\).*/\2/p;d' file

如上标题:

 sed '/^DISK_2/s/\(\S*\s*\)\{3\}\(\S*\).*/\2/;s/^/ GB FREE\n--------\n/p;d' file