AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 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 Script para encontrar string no arquivo de log

  • 772

Eu tenho um script que corresponde a uma string em um diretório do número de arquivos de log conforme abaixo:

#!/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" {} \;

Isso gera uma lista de arquivos de log que contém a string pesquisada. Por exemplo:

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

Eu quero esta saída como lista como:

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

E vai pedir o número 1/2/3/4/5/6 para inserir que vai abrir aquele arquivo numerado, ou seja; se eu pressionar 4, ele enviará o comando

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

e a string "2001NM-100313" será pesquisada em todo o arquivo.

Meu objetivo é ler toda a linha/linhas (pode haver várias linhas com a string) que contêm essa string dos arquivos de log, pode haver vários arquivos de log que possuem essa string com várias datas, preciso selecionar qualquer arquivo datado e leia o registro.

shell scripting
  • 2 2 respostas
  • 18486 Views

2 respostas

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

    Basta usar select(o bashbuiltin).

    $ 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.
    $
    

    Então o código que você quer é provavelmente:

    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
    

    Observe que, se seus nomes de arquivo contiverem espaços em branco, isso será interrompido. Veja também:

    • Por que o loop sobre a saída de find é uma prática ruim?

    No entanto, se você chamar o selectbuilt-in diretamente de find, isso manipulará os espaços em branco com facilidade. Portanto, o seguinte é realmente melhor em todos os casos em que consigo pensar:

    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

    Ler sua pergunta me lembrou de sempre querer ter um script simples que tornasse mais fácil para mim pesquisar arquivos por uma string específica e, em seguida, examinar um dos arquivos que contêm a string. Com base no seu script e na sugestão da saga de usar um array, criei meu script e também finalizei o seu. :)

    Observação: este script é /bin/bash, não /bin/sh, porque não sei como fazer o array funcionar em /bin/sh...

    Seu roteiro:

    #!/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
    

    EDIT: Embora o script acima funcione perfeitamente bem para a pergunta original, desenvolvi a resposta do Wildcard, para que meu script possa lidar com arquivos com espaços vazios e oferece várias ferramentas para abrir o arquivo selecionado.

    meu roteiro:

    #!/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

relate perguntas

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Renomeie (acrescentar) arquivos CSV em massa com base em um valor dentro

  • Como salvar um caminho com ~ em uma variável?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Matriz JSON para bash variáveis ​​usando jq

    • 4 respostas
  • Marko Smith

    A data pode formatar a hora atual para o fuso horário GMT? [duplicado]

    • 2 respostas
  • Marko Smith

    bash + lê variáveis ​​e valores do arquivo pelo script bash

    • 4 respostas
  • Marko Smith

    Como posso copiar um diretório e renomeá-lo no mesmo comando?

    • 4 respostas
  • Marko Smith

    conexão ssh. Conexão X11 rejeitada devido a autenticação incorreta

    • 3 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Marko Smith

    comando systemctl não funciona no RHEL 6

    • 3 respostas
  • Marko Smith

    rsync porta 22 e 873 uso

    • 2 respostas
  • Marko Smith

    snap /dev/loop em 100% de utilização -- sem espaço livre

    • 1 respostas
  • Marko Smith

    chave de impressão jq e valor para todos no subobjeto

    • 2 respostas
  • Martin Hope
    EHerman Matriz JSON para bash variáveis ​​usando jq 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux A data pode formatar a hora atual para o fuso horário GMT? [duplicado] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC Como posso copiar um diretório e renomeá-lo no mesmo comando? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve Como as permissões de arquivo funcionam para o usuário "root"? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey Como baixar o pacote não instalá-lo com o comando apt-get? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao Por que os diretórios /home, /usr, /var, etc. têm o mesmo número de inode (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg — o comando list-keys gera uid [ desconhecido ] depois de importar a chave privada para uma instalação limpa 2017-11-26 18:26:02 +0800 CST

Hot tag

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

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve