使用AWK从两个不同的现场分离器打印值?

时间:2017-03-21 09:56:59

标签: bash awk gawk

我有来自nmap的以下(略微修剪)日志文件:

    <html>  
    <body>  
       <form action="" method="post" enctype="multipart/form-data">  
       <div style="width:200px;border-radius:6px;margin:0px auto">  
    <table border="1">  
       <tr>  
          <td colspan="2">Select Technolgy:</td>  
       </tr>  
       <tr>  
          <td>PHP</td>  
          <td><input type="checkbox" name="techno[]" value="PHP"></td>  
       </tr>  
       <tr>  
          <td>.Net</td>  
          <td><input type="checkbox" name="techno[]" value=".Net"></td>  
       </tr>  
       <tr>  
          <td>Java</td>  
          <td><input type="checkbox" name="techno[]" value="Java"></td>  
       </tr>  
       <tr>  
          <td>Javascript</td>  
          <td><input type="checkbox" name="techno[]" value="javascript"></td>  
       </tr>  
       <tr>  
          <td colspan="2" align="center"><input type="submit" value="submit" name="sub"></td>  
       </tr>  
    </table>  
    </div>  
    </form>  
    <?php  
    if(isset($_POST['sub']))  
    {  
    $host="localhost";//host name  
    $username="root"; //database username  
    $word="";//database word  
    $db_name="dbtask";//database name  
    $tbl_name="new"; //table name  
    $con=mysqli_connect("$host", "$username", "$word","$db_name")or die("cannot connect");//connection string  
    $checkbox1=$_POST['techno'];  
    $chk="";  
    foreach($checkbox1 as $chk1)  
       {  
          $chk .= $chk1.",";  
       }  
    $in_ch=mysqli_query($con,"insert into new(time) values ('$chk')");  
    if($in_ch==1)  
       {  
          echo'<script>alert("Inserted Successfully")</script>';  
       }  
    else  
       {  
          echo'<script>alert("Failed To Insert")</script>';  
       }  
    }  
    ?>  
    </body>  
    </html>  

我尝试使用awk打印出ip,然后是机器类型。示例输出如下所示:

  

111.111.111.5 Windows XP

使用AWK我已经提取了ip地址和一些信息:

Host: 111.111.111.5 ()  Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows XP microsoft-ds/
Host: 111.111.111.10 () Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server 2003 3790 Service Pack 2 microsoft-ds/
Host: 111.111.111.31 () Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server 2003 3790 Service Pack 1 microsoft-ds/
Host: 111.111.111.73 () Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 7 Professional 7601 Service Pack 1 microsoft-ds/
Host: 111.111.111.128 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 2000 microsoft-ds/
Host: 111.111.111.145 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server (R) 2008 Standard 6001 Service Pack 1 microsoft-ds/
Host: 111.111.111.202 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 2000 microsoft-ds/
Host: 111.111.111.218 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 7 Professional 7601 Service Pack 1 microsoft-ds/
Host: 111.111.111.220 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server 2008 R2 Standard 7601 Service Pack 1 microsoft-ds/
Host: 111.111.111.221 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server (R) 2008 Standard 6001 Service Pack 1 microsoft-ds/
Host: 111.111.111.223 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server (R) 2008 Standard 6001 Service Pack 1 microsoft-ds/
Host: 111.111.111.227 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 2000 microsoft-ds/
Host: 111.111.111.229 ()    Ports: 139/open/tcp//netbios-ssn//Windows Server 2003 3790 Service Pack 1 netbios-ssn/, 445/filtered/tcp//microsoft-ds///
Host: 111.111.111.230 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 7 Ultimate N 7600 microsoft-ds/

但是我需要使用不同的字段分隔符来提取我认为的操作系统信息?有没有办法在不创建专门用于该任务的python脚本的情况下解决这个问题?

3 个答案:

答案 0 :(得分:3)

这样的事情:

awk -F\/ '{sub(/^[^ ]+ /,"",$1); sub(/ .*/,"", $1); sub(/ [^ ]*$/,"",$(NF-1)); print $1, $(NF-1)}' File

111.111.111.5 Windows XP
111.111.111.10 Windows Server 2003 3790 Service Pack 2
111.111.111.31 Windows Server 2003 3790 Service Pack 1
111.111.111.73 Windows 7 Professional 7601 Service Pack 1
111.111.111.128 Windows 2000
111.111.111.145 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.202 Windows 2000
111.111.111.218 Windows 7 Professional 7601 Service Pack 1
111.111.111.220 Windows Server 2008 R2 Standard 7601 Service Pack 1
111.111.111.221 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.223 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.227 Windows 2000
111.111.111.229
111.111.111.230 Windows 7 Ultimate N 7600

在倒数第二行..服务器名称出现在不同的位置,因此不会在输出中打印。因此,如果服务器名称可能出现在两个位置中的任何一个位置,那么您可以选择:

awk -F\/ '{sub(/^[^ ]+ /,"",$1); sub(/ .*/,"",$1); sub(/ [^ ]*$/,"",$(NF-1)); sub(/ [^ ]*$/,"",$7); print $1, $(NF-1), $7}' File

111.111.111.5 Windows XP
111.111.111.10 Windows Server 2003 3790 Service Pack 2
111.111.111.31 Windows Server 2003 3790 Service Pack 1
111.111.111.73 Windows 7 Professional 7601 Service Pack 1
111.111.111.128 Windows 2000
111.111.111.145 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.202 Windows 2000
111.111.111.218 Windows 7 Professional 7601 Service Pack 1
111.111.111.220 Windows Server 2008 R2 Standard 7601 Service Pack 1
111.111.111.221 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.223 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.227 Windows 2000
111.111.111.229  Windows Server 2003 3790 Service Pack 1
111.111.111.230 Windows 7 Ultimate N 7600

如果您只想过滤Windows个部分:

 awk -F\/ '/Windows/ {sub(/^[^ ]+ /,"",$1); sub(/ .*/,"",$1); sub(/ [^ ]*$/,"",$(NF-1)); sub(/ [^ ]*$/,"",$7); print $1, $(NF-1), $7}' File

答案 1 :(得分:2)

作为替代方案,您可以使用所有线路,因为您要打印的系统信息始终是最后一个字段($ NF):

$ a="Host: 111.111.111.230 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 7 Ultimate N 7600 microsoft-ds/"
$ awk -F'/' '{split($1,f," ");print f[2],$(NF-1)}' <<<"$a"
#output
111.111.111.230 Windows 7 Ultimate N 7600 microsoft-ds

顺便说一句,您可以在GNU awk中使用多个分隔符,如下所示:

$ a="Host: 111.111.111.5 ()  Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows XP microsoft-ds/"
$ awk -F"[ //]" '{print $2,$20,$21,$22}' <<<"$a"  #delimiter is space and //
#output:
111.111.111.5 Windows XP microsoft-ds

但是在你的文件中第二种方法不能正常工作,因为文档结构在所有行中都不一样。

答案 2 :(得分:2)

awk中的替代方案。删除最后一个字段($NF),printf $6的最后一部分(= Windows)以及之后的所有内容。无需摆弄FS

$ awk '
{
    NF--; $0=$0                            # remove last field
    n=split($6,a,"/")                      # split $6 by /s
    printf "%s %s ", $2,a[n]               # output last a[]
    for(i=7; i<=NF; i++)                   # iterate the rest of fields
        printf "%s%s", $i, (i<NF?OFS:ORS)  # output
}' foo
111.111.111.5 Windows XP
111.111.111.10 Windows Server 2003 3790 Service Pack 2
111.111.111.31 Windows Server 2003 3790 Service Pack 1