AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 407413
Accepted
Tasbir
Tasbir
Asked: 2017-11-28 20:47:57 +0800 CST2017-11-28 20:47:57 +0800 CST 2017-11-28 20:47:57 +0800 CST

用于在日志文件中查找字符串的 Shell 脚本

  • 772

我有一个脚本,它与来自多个日志文件的目录中的字符串匹配,如下所示:

#!/bin/sh
# Collect Customer ID as input
read -p "Enter Customer ID: " custid
echo "Searched customer ID $custid found in following logs: "
# Find the customer id as string in specified directory
find /usr/local/tomcat9/logs/ -type f -exec grep -l "$custid" {} \;

这将输出包含搜索字符串的日志文件列表。例如:

Enter Customer ID: 2001NM-100313
Searched customer ID 2001NM-100313 found in following logs:
/usr/local/tomcat9/logs/localhost_access_log.2017-10-04.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-07-11.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-11-02.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-09-11.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-08-09.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-06-11.txt

我希望这个输出像列表一样:

1. /usr/local/tomcat9/logs/localhost_access_log.2017-10-04.txt
2. /usr/local/tomcat9/logs/localhost_access_log.2017-07-11.txt
3. /usr/local/tomcat9/logs/localhost_access_log.2017-11-02.txt
4. /usr/local/tomcat9/logs/localhost_access_log.2017-09-11.txt
5. /usr/local/tomcat9/logs/localhost_access_log.2017-08-09.txt
6. /usr/local/tomcat9/logs/localhost_access_log.2017-06-11.txt

它会要求输入数字 1/2/3/4/5/6 以打开该编号文件,即;如果我按 4 它将发送命令

vim /usr/local/tomcat9/logs/localhost_access_log.2017-09-11.txt

并且将在整个文件中搜索字符串“2001NM-100313”。

我的目标是从日志文件中读取包含此字符串的整行/行(字符串可能有多行),可能有多个日志文件具有此字符串和多个日期,我需要选择任何日期文件并阅读日志。

shell scripting
  • 2 2 个回答
  • 18486 Views

2 个回答

  • Voted
  1. Wildcard
    2017-11-29T00:27:09+08:002017-11-29T00:27:09+08:00

    只需使用select(bash内置)。

    $ help select
    select: select NAME [in WORDS ... ;] do COMMANDS; done
        The WORDS are expanded, generating a list of words.  The
        set of expanded words is printed on the standard error, each
        preceded by a number.  If `in WORDS' is not present, `in "$@"'
        is assumed.  The PS3 prompt is then displayed and a line read
        from the standard input.  If the line consists of the number
        corresponding to one of the displayed words, then NAME is set
        to that word.  If the line is empty, WORDS and the prompt are
        redisplayed.  If EOF is read, the command completes.  Any other
        value read causes NAME to be set to null.  The line read is saved
        in the variable REPLY.  COMMANDS are executed after each selection
        until a break command is executed.
    $
    

    所以你想要的代码可能是:

    read -p 'Enter Customer ID: ' custid
    select f in $(find /usr/local/tomcat9/logs -type f -exec grep -q -e "$custid" {} \; -print); do
      vim "$f"
    done
    

    请注意,如果您的文件名包含空格,则会中断。也可以看看:

    • 为什么循环查找的输出是不好的做法?

    但是,如果您select直接从 调用内置函数find,这将轻松处理空格。因此,在我能想到的所有情况下,以下内容实际上都更好:

    read -p 'Enter customer ID: ' custid
    find /usr/local/tomcat9/logs -type f -exec grep -qe "$custid" {} \; -exec bash -c '
      select f; do vim "$f"; done' find-sh {} +
    
    • 4
  2. Best Answer
    Johano Fierra
    2017-11-28T23:59:49+08:002017-11-28T23:59:49+08:00

    阅读你的问题提醒我一直想要一个简单的脚本,让我更容易在文件中搜索特定字符串,然后查看包含该字符串的文件之一。在您的脚本和 saga 建议使用数组的基础上,我创建了我的脚本并完成了您的脚本。:)

    请注意:这个脚本是 /bin/bash,而不是 /bin/sh,因为我不知道如何让数组在 /bin/sh 中工作...

    你的脚本:

    #!/bin/bash
    # Collect Customer ID as input
    read -p "Enter Customer ID: " custid
    echo "Searched customer ID $custid found in following logs: "
    # Find the customer id as string in specified directory
    
    arr=( $(find /usr/local/tomcat9/logs/ -type f -exec grep -l "$custid" {} \; | sort -r) )
    
    if [ ${#arr[@]} -eq 0 ]; then
        echo "No matches found."
    else
        arr+=('Quit')
        select opt in "${arr[@]}"
        do
            case $opt in
                "Quit")
                    break
                    ;;
                *)
                    vim $opt
                    break
                    ;;
            esac
        done
    fi
    

    编辑:虽然上面的脚本可以很好地解决原始问题,但我建立在 Wildcard 的答案之上,因此我的脚本可以处理带有空格的文件并提供各种工具来打开所选文件。

    我的脚本:

    #!/bin/bash
    # Find string in files of given directory (recursively)
    
    read -p "Enter search string: " text
    read -p "Enter directory: " directory
    
    #arr=( $(find $directory -type f -exec grep -l "$text" {} \; | sort -r) )
    #find $directory -type f -exec grep -qe "$text" {} \; -exec bash -c '
    
    file=$(find $directory -type f -exec grep -qe "$text" {} \; -exec bash -c 'select f; do echo $f; break; done' find-sh {} +;)
    
    if [ -z "$file" ]; then
        echo "No matches found."
    else
        echo "select tool:"
        tools=("nano" "less" "vim" "quit")
        select tool in "${tools[@]}"
        do
            case $tool in
                "quit")
                    break
                    ;;
                *)
                    $tool $file
                    break
                    ;;
            esac
        done
    fi
    
    • 2

相关问题

  • FreeBSD 的 sh:列出函数

  • 有没有办法让 ls 只显示某些目录的隐藏文件?

  • grep -v grep 有什么作用

  • 根据其中的值批量重命名(附加)CSV 文件

  • 如何将带有〜的路径保存到变量中?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    JSON数组使用jq来bash变量

    • 4 个回答
  • Marko Smith

    日期可以为 GMT 时区格式化当前时间吗?[复制]

    • 2 个回答
  • Marko Smith

    bash + 通过 bash 脚本从文件中读取变量和值

    • 4 个回答
  • Marko Smith

    如何复制目录并在同一命令中重命名它?

    • 4 个回答
  • Marko Smith

    ssh 连接。X11 连接因身份验证错误而被拒绝

    • 3 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Marko Smith

    systemctl 命令在 RHEL 6 中不起作用

    • 3 个回答
  • Marko Smith

    rsync 端口 22 和 873 使用

    • 2 个回答
  • Marko Smith

    以 100% 的利用率捕捉 /dev/loop -- 没有可用空间

    • 1 个回答
  • Marko Smith

    jq 打印子对象中所有的键和值

    • 2 个回答
  • Martin Hope
    EHerman JSON数组使用jq来bash变量 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux 日期可以为 GMT 时区格式化当前时间吗?[复制] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC 如何复制目录并在同一命令中重命名它? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve “root”用户的文件权限如何工作? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey 如何下载软件包而不是使用 apt-get 命令安装它? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao 为什么目录 /home、/usr、/var 等都具有相同的 inode 编号 (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg —list-keys 命令在将私钥导入全新安装后输出 uid [未知] 2017-11-26 18:26:02 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve