【问题标题】:Need to parse a log file in bash需要在bash中解析一个日志文件
【发布时间】:2012-09-26 14:07:42
【问题描述】:

我有一个包含大量文本的日志文件,其中一些是无用的。在这个日志中有一些对我很重要的行。这些线的模式是:

 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x00000001 (NEEDED)                     Shared library: [ld.so.1]
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]

NEEDED 关键字可以在对我来说很重要的所有行中找到。 [] 之间的关键字对我来说很重要。我需要创建所有这些字符串的列表,而不是重复它们。

我已经在 Python 上完成了这项工作,但看起来在我想要运行脚本的机器上没有可用的 Python,所以我需要在 bash 中重新编写脚本。我只知道 bash 中的基本知识,无法找到解决问题的方法。

我使用的 Python 脚本是:

import sys
import re


def testForKeyword(keyword, line):
    findStuff = re.compile(r"\b%s\b" % keyword, \
                                   flags=re.IGNORECASE)

    if findStuff.search(line):
        return True
    else:
        return False

# Get filename argument
if len(sys.argv) != 2:
    print("USAGE: python libraryParser.py <log_file.log>")
    sys.exit(-1)

file = open(sys.argv[1], "r")

sharedLibraries = []
for line in file:
    if testForKeyword("NEEDED", line):
        libraryNameStart = line.find("[") + 1
        libraryNameFinish = line.find("]")

        libraryName = line[libraryNameStart:libraryNameFinish]

        # No duplicates, only add if it does not exist
        try:
            sharedLibraries.index(libraryName)
        except ValueError:
            sharedLibraries.append(libraryName)

for library in sharedLibraries:
    print(library)

你能帮我解决这个问题吗? 提前致谢。

【问题讨论】:

  • 一种解决方案是使用grep 拉出所有包含“NEEDED”的行,然后使用cut 在方括号上拆分行,然后使用uniq 删除所有重复项。跨度>
  • 你想要什么? .so 的列表?
  • 你在 Python 中的“算法”是什么样的?你需要展示一些工作让我们帮忙。想想你的 python 代码中发生了哪些步骤。然后像“这是我在 python 中执行的步骤,1. .... 2 .... 3....,shell 中的等效或最佳实践技术是什么?”这样的问题。将表明您不只是在寻找一些免费的咨询。 (编辑您的问题,不要在 cmets 中回复;-)。祝你好运。
  • 哪个版本的 Bash? bash 3 及更高版本支持类似于 Python(扩展 RE)的 RE 以及捕获。您也许可以重用您的 Python RE(假设您使用过它)
  • 是的,没错,我需要创建一个唯一的 .so 列表。

标签: bash shell awk


【解决方案1】:
$ awk -F'[][]' '/NEEDED/ {print $2}' data.txt | sort | uniq
ld.so.1
libc.so.6
libgcc_s.so.1
libm.so.6

仅限awk:

$ awk -F'[][]' '/NEEDED/ {save[$5]++}END{ for (i in save) print i}' data.txt
libc.so.6
libm.so.6
libgcc_s.so.1
ld.so.1

简化你的 python 代码:

#!/usr/bin/env python

libs = []

with open("data.txt") as fd:
    for line in fd:
        if "NEEDED" in line:
            libs.append(line.split()[4])

for i in set(libs):
    print i

Bash 解决方案(没有唯一库)

#!/bin/bash

while IFS='][' read -a array
do
    echo ${array[1]}
done < data.txt

【讨论】:

    【解决方案2】:

    一种使用awk 的方法,假设infile 带有问题的数据:

    awk '
        $2 ~ /NEEDED/ { 
            lib = substr( $NF, 2, length($NF) - 2 ); 
            libs[ lib ] = 1;
        } 
        END { 
            for (lib in libs) { 
                printf "%s\n", lib;
            } 
        }
    ' infile
    

    输出:

    libc.so.6                                                                                                                                                                                                                                    
    libgcc_s.so.1                                                                                                                                                                                                                                
    ld.so.1                                                                                                                                                                                                                         
    libm.so.6
    

    【讨论】:

    • 我想这就是我要找的。非常感谢!
    【解决方案3】:

    使用grepcoreutils

    grep NEEDED infile | grep -o '\[[^]]*\]' | tr -d '][' | sort | uniq
    

    输出:

    ld.so.1
    libc.so.6
    libgcc_s.so.1
    libm.so.6
    

    【讨论】:

      【解决方案4】:

      awk -F '[' ' /NEEDED/ { print $NF } ' file_name | sed 's/]//' | sort | uniq

      【讨论】:

        【解决方案5】:

        如果您将日志保存在名为“log.txt”的文件中,则可以获取它:

        grep "(NEEDED)" log.txt | awk -F"\[" '{print substr($2,0,length($2));}' - | sort -u
        

        使用 sort -u 你不会得到重复的行。

        【讨论】:

          【解决方案6】:
           awk '/NEEDED/ {gsub("[][]", ""); print $5}' < /tmp/1.txt  | sort -u
          

          【讨论】:

          • 我不知道uniq 命令也执行所需的预排序';-)。祝大家好运
          【解决方案7】:

          sed 解决方案可能是:

          sed -e '/(needed)/!d' -e 's/\(.*\[\)\|\(\]$\)//g' INPUTFILE
          

          注意,如果你在 Windows 上,正确的做法是:

          sed -e '/(needed)/!d' -e 's/\(.*\[\)\|\(\].$\)//g' INPUTFILE
          
          1. 第一个-e 部分删除与(needed) 不匹配的每一行
          2. 第二个删除直到最后一个[ 和最后一个] 之前的所有内容(在Windows 上\n 之前的\r(回车),但这不是问题,因为输出打印正确...

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-07
            • 1970-01-01
            • 2017-05-23
            • 1970-01-01
            • 2016-01-09
            相关资源
            最近更新 更多