使用awk或bash过滤文本以及某些特定条件

时间:2017-07-22 16:29:46

标签: bash awk sed filtering lines

我有一个输出(一个众所周知的btmon工具),如下例所示,我需要解析它并从下面获取一些信息:如果UUID出现在{{1然后它等于HCI event:,然后取32f9169f-4feb-4883-ade6-1f0127018db3Address:字段的值并将它们放在一起并创建一个新行。此外,每个实例都应根据[hci]编号(与HCI事件相同的行)放入特定文件中。例如,从hci 0的每个HCI事件(满足描述的条件),它将转到文件-hci0.txt,来自hci1对于hci0(.txt)来说,以这种格式为所有hciX提供文件-hci1.txt等等:

  

A0:E6:F8:48:38:6F AB

     

A0:E6:F8:48:87:DA B6

表示hci1(.txt):

  

A0:E6:F8:48:32:94 C3

     

A0:E6:F8:48:EF:78 BA

所以这是我需要以所描述的方式解析的流或文件:

RSSI:

3 个答案:

答案 0 :(得分:2)

在Ruby,awk,Python,Perl中你可以:

  1. 将文本分成块;
  2. 测试每个块以了解您描述的三个正则表达式测试;
  3. 解析块;
  4. 打印到相应的文件。
  5. 第一部分是通过使用sed在块之间添加\n,然后使用awk来处理每个块来辅助的。这里sedawk正在生成感兴趣的块(其中2个):

    $ sed 's/^>/\
    &/' file | awk -v RS="" -v FS="\n" '
      /UUIDs/ && /32f9169f-4feb-4883-ade6-1f0127018db3/ && /\[hci[01]\]/' 
    

    现在将awk添加到这两个文件中的块:

    $ sed 's/^>/\
    &/' file | 
    awk -v RS="" -v FS="\n" '
      /UUIDs/ && /32f9169f-4feb-4883-ade6-1f0127018db3/ && /\[hci[0-9]+\]/ {
          s1=s2=fo=""
          for (i=1;i<=NF;i++) {
                if (match($i,/\[hci[0-9]+/))
                     fn=substr($i,RSTART+1,RLENGTH-1)
                if (match($i,/Address: /))
                     s1=substr($i,RSTART+RLENGTH, 17)
                else if (match($i,/ RSSI:/)) {
                     match($i,/\(0x[^)]+\)/)
                     s2=toupper(substr($i,RSTART+3, RLENGTH-4))  
                }
            }
         fo="file-" fn ".txt"   
         print s1 " " s2 " => " fo
         print s1 " " s2 > fo
    }'    
    
    $ cat file-hci0.txt
    A0:E6:F8:48:38:6F AB
    A0:E6:F8:48:87:DA B6 
    $ cat file-hci1.txt
    A0:E6:F8:48:32:94 C3
    A0:E6:F8:48:EF:78 BA  
    

答案 1 :(得分:0)

脚本文件:

$1 == ">" {
          cnt++
          for (i=1;i<=NF;i++) {
                if ( $i ~ /\[.*\]/ ) {
                                 hci[cnt]=substr($i,2,length($i)-2)
                        }
                }
        }
$1 == "Address:" {
           add[cnt]=$2
        }
$0 ~ /32f9169f-4feb-4883-ade6-1f0127018db3/ {
           fnd[cnt]=""
        }
$1 == "RSSI:"   {
           str=substr($4,length($4)-2)
           gsub("\)","",str)
           rssi[cnt]=toupper(str)
        }
END {
           for (i in fnd) {
                        print add[i]" "rssi[i] > "file-"hci[i]".txt"
                }
    }




awk -f scriptfile filename

使用awk并使用awk代码的脚本文件,当我们遇到&#34;&gt;&#34;这表示新的数据块,因此我们增加变量cnt。然后,我们循环遍历此行上的每个字段,并以[以[结尾]开头的任何字段进行检查。然后,此文本将[和]与substr一起删除,并添加到使用cnt索引的数组hci中。然后,我们将所有地址存储在数组add中,并在rssi中存储RSSI文本(使用substr和gsub格式化)。如果匹配mac地址,则创建数组fnd。所有数组都由cnt索引。我们最终遍历fnd并从其他数组中提取其他数据,打印所需的输出并重定向以创建所需的文件。

答案 2 :(得分:0)

尝试关注并告诉我这是否对您有所帮助。

awk '/> HCI Event/ && a && b{print val1,toupper(substr(val2,4,2));a=b=""} /> HCI Event/{a=1;} /UUID/ && a{getline;sub(/^[[:space:]]+/,"");if($0 == "32f9169f-4feb-4883-ade6-1f0127018db3"){b=1}} /Address/ && a{val1=$2;} /RSSI/ && a{val2=$4;}'  Input_file

很快就会添加非单一衬里形式的解决方案。

编辑:现在也添加非单一形式的解决方案。

awk '/> HCI Event/ && a && b{
        print val1,toupper(substr(val2,4,2));a=b=""}
    /> HCI Event/{a=1;}
    /UUID/ && a  {
        getline;
        sub(/^[[:space:]]+/,"");
        if($0 == "32f9169f-4feb-4883-ade6-1f0127018db3"){b=1}
                 }
    /Address/ && a{val1=$2;}
    /RSSI/ && a{val2=$4;}
    '   Input_file