Shell Script para localizar uma string no arquivo de log

1

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 ele pedirá o número 1/2/3/4/5/6 para entrada que abrirá esse 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 alvo é 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 tenham essa string com várias datas, eu preciso selecionar qualquer arquivo datado e leia o log.

    
por Tasbir 28.11.2017 / 05:47

2 respostas

1

Ao ler sua pergunta, lembrei-me sempre de ter um script simples que facilitasse a busca de arquivos por uma determinada string e, em seguida, analisasse um dos arquivos que continha a string. Com base no seu script e na sugestão da saga de usar uma matriz, criei meu script e também terminei o seu. :)

Por favor, note: Este script é / bin / bash, não / bin / sh, porque eu não sei como fazer o array funcionar em / bin / sh ...

Seu script:

#!/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 para a pergunta original, eu construí sobre a resposta de Wildcard, então meu script pode manipular arquivos com espaços vazios e oferece várias ferramentas para abrir o arquivo selecionado. arquivo.

Meu script:

#!/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
    
por 28.11.2017 / 08:59
3

Use apenas select (o bash incorporado).

$ 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 os nomes dos seus arquivos contiverem espaços em branco, isso será interrompido. Veja também:

No entanto, se você chamar o select incorporado diretamente de find , isso manipulará os espaços em branco com facilidade. Então, o seguinte é realmente melhor em todos os casos em que posso 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 {} +
    
por 28.11.2017 / 09:27