从字符串中提取东西..(从字符串中提取整数)

时间:2017-11-08 08:10:48

标签: string awk sed extraction numerical

在bash中,我试图从这样的字符串中提取一些数据:

OK - C: Total=49.90GB, Used=42.53GB (85.2%), Free=7.36GB (14.8%)     |'C: Space'=42.53GB; 'C: Utilisation'=85.2%;

我想提取49.90,42.537.36,甚至更好49,427

有些像'/=/{print $4}'这样的awk我得到了

Total=49.90GB

有没有办法只用一个命令提取数字字符串?

由于

3 个答案:

答案 0 :(得分:0)

使用gawkmatch(target,regex,array)功能:

awk '{match($0,/.*Total=([^.]+).*Used=([^.]+).*Free=([^.]+).*/,a);print a[1],a[2],a[3]}' input_file
49 42 7

或者您可以使用grep将值存储在不同的变量中:

var1=$(grep -oP 'Total=\K[^.]+' input)
var2=$(grep -oP 'Free=\K[^.]+' input)
var3=$(grep -oP 'Used=\K[^.]+' input)

答案 1 :(得分:0)

更多方法,使用RS / match() /循环播放字段

输入:

$ cat infile
OK - C: Total=49.90GB, Used=42.53GB (85.2%), Free=7.36GB (14.8%)     |'C: Space'=42.53GB; 'C: Utilisation'=85.2%;
  

我想提取49.90,42.53和7.36,甚至更好49,42和   7。

使用RS

输出-1:

# for-I would like to extract 49.90,42.53 and 7.36,
$ awk -v RS=' ' -F'=' -v OFS=','   'c==3{exit}/^(Total|Used|Free)=/{c++; gsub(/GB|,/,"",$2); printf("%s%s",$2,c==3?"\n":OFS)}' infile
49.90,42.53,7.36

输出-2:

# for - or even better 49,42 and 7.
$ awk -v RS=' ' -F'=' -v OFS=','   'c==3{exit}/^(Total|Used|Free)=/{c++; gsub(/\..*/,"",$2); printf("%s%s",$2,c==3?"\n":OFS)}' f2
49,42,7

更好的可读性:

awk -v RS=' ' -F'=' -v OFS=','   '
              c==3{exit}
              /^(Total|Used|Free)=/{
                      c++; 
                      gsub(/GB|,/,"",$2); 
                      printf("%s%s",$2,c==3?"\n":OFS)
              }
              ' infile

使用match

$ awk -v OFS=, '{s="";while(match($0,/(Total|Used|Free)=[^ ,]+/)){t=substr($0,RSTART,RLENGTH); gsub(/.*=|GB/,"",t); s=(s?s OFS:"") t;$0=substr($0,RSTART+RLENGTH)}print s}' infile
49.90,42.53,7.36

更好的可读性:

awk -v OFS=, '{
                s="";
                while(match($0,/(Total|Used|Free)=[^ ,]+/)){
                     t=substr($0,RSTART,RLENGTH); 
                     gsub(/.*=|GB/,"",t);
                     s=(s?s OFS:"") t;
                     $0=substr($0,RSTART+RLENGTH)
                 }
                 print s
               }
              ' infile

循环浏览字段

$ awk -v OFS=, '{s="";for(i=1; i<=NF;i++)if($i~/(Total|Used|Free)=/){ gsub(/.*=|GB|,/,"",$i); s=(s?s OFS:"") $i;} print s}' infile
49.90,42.53,7.36

更好的可读性:

awk -v OFS=, '{
               s="";
               for(i=1; i<=NF;i++)
                   if($i~/(Total|Used|Free)=/)
                   { 
                     gsub(/.*=|GB|,/,"",$i); 
                     s=(s?s OFS:"") $i;
                   } 
                print s
               }
              ' infile

<强>解释

  • RS=' ' - 将行分隔符设置为单个空格
  • -F'=' - 将字段/列分隔符设置为=
  • -v OFS=',' - 设置输出字段/列分隔符为逗号,

默认情况下awk使用\n换行符作为行分隔符,但是这里我们强制awk将空格读取为行分隔符,所以当你将空格设置为行分隔符时,awk会按如下方式读取你的文件

$ awk -v RS=' ' '{print "Line No:",NR,"=>", $0}' f2
Line No: 1 => OK
Line No: 2 => -
Line No: 3 => C:
Line No: 4 => Total=49.90GB,
Line No: 5 => Used=42.53GB
Line No: 6 => (85.2%),
Line No: 7 => Free=7.36GB
Line No: 8 => (14.8%)
Line No: 9 => 
Line No: 10 => 
Line No: 11 => 
Line No: 12 => 
Line No: 13 => |'C:
Line No: 14 => Space'=42.53GB;
Line No: 15 => 'C:
Line No: 16 => Utilisation'=85.2%;
  • c==3{exit}当变量c等于3时,退出

  • /^(Total|Used|Free)=/如果行/记录/行以列表中的任何一个开头,那么

  • c++发布增量计数器变量,单个我们想要3个字段,当它变为3时,我们只在我们的printf语句中添加换行符

  • gsub(/GB|,/,"",$2);全局替换,在第二列中将GB或逗号替换为null

  • printf("%s%s",$2,c==3?"\n":OFS)直到变量c变为3,我们打印第二列,输出字段分隔符(,),当c变为3时,我们就完成了,所以打印换行符。

答案 2 :(得分:0)

使用GNU awk for FPAT:

$ awk -v FPAT='[0-9.]+' '{print $1, $2, $4}' file
49.90 42.53 7.36

$ awk -v FPAT='[0-9.]+' '{printf "%d %d %d\n", $1, $2, $4}' file
49 42 7
相关问题