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 / 411769
Accepted
xMaNuu
xMaNuu
Asked: 2017-12-20 02:02:37 +0800 CST2017-12-20 02:02:37 +0800 CST 2017-12-20 02:02:37 +0800 CST

leia o arquivo linha por linha e lembre-se da última posição no arquivo

  • 772

Eu quero grep alguma linha de um arquivo de log com uma entrada de outro arquivo. Estou usando este pequeno comando para fazer isso:

while read line; do 
    grep "$line" service.log; 
done < input_strings.txt > result.txt

input_strings.txttem cerca de 50.000 strings (uma por linha). Para cada uma dessas strings, estou pesquisando o service.logarquivo enorme (com cerca de 2.000.000 de linhas).

Então, digamos que a primeira string de input_strings.txtseja encontrada na service.loglinha 10 000, esta linha é gravada no meu arquivo result.txt. Depois disso, a 2ª string de input_strings.txtserá pesquisada em service.log, MAS iniciando na linha 1 de service.log.

Como posso me lembrar da última linha em que encontrei a primeira entrada service.log? Para que eu possa iniciar a 2ª busca por lá?

files read
  • 2 2 respostas
  • 1403 Views

2 respostas

  • Voted
  1. Best Answer
    igal
    2017-12-20T02:09:48+08:002017-12-20T02:09:48+08:00

    Se você deseja obter as correspondências, não precisa usar um loop. Seria muito mais rápido usar apenas um único grepcomando:

    grep -Ff input_strings service.log > results.txt
    

    Dito isso, se você quiser fazer literalmente o que afirmou em sua pergunta, poderá usar uma variável para acompanhar a linha na qual a última correspondência foi encontrada:

    LINE_NUMBER=0
    while read LINE; do
    
        # Search for the next match starting at the line number of the previous match
        MATCH="$(tail -n+${LINE_NUMBER} "service.log" | grep -n "${LINE}" | head -n1)";
    
        # Extract the line number from the match result
        LINE_NUMBER="${MATCH/:*/}";
    
        # Extract the matching string from the match result
        STRING="${x#*:}";
    
        # Output the matching string
        echo "${STRING}";
    
    done < input_strings.txt > result.txt
    
    • 3
  2. ilkkachu
    2017-12-20T02:35:16+08:002017-12-20T02:35:16+08:00

    Percebi que você deseja pesquisar a primeira palavra-chave e, em seguida, continuar na linha após essa correspondência para pesquisar a próxima palavra-chave etc., imprimindo as correspondências à medida que avança.

    Dado keywords:

    foo
    bar
    

    E data:

    bar 0
    foo 1
    bar 1
    foo 2
    

    O awkscript aqui deve fazer exatamente isso (testado com GNU awk):

    $ awk 'BEGIN {i = j = 0} NR==FNR { k[i++] = $0; next} 
           $0 ~ k[j] {j++; print $0} j >= i {exit}' keywords data 
    foo 1
    bar 1
    

    ie jcomece em 0, e durante o primeiro arquivo ( NR==FNRcompara o número de registro/linha do arquivo atual com o número total de linhas vistas), coletamos as palavras-chave para um array. Depois disso, tente corresponder à jpalavra-chave :th e imprima e aumente jem uma correspondência. Sair depois que todas as palavras-chave forem encontradas.

    Assim como grep, as palavras-chave aqui são, na verdade, padrões regex, embora obviamente sejam awkregexes aqui. Se você deseja pesquisar strings fixas, use index($0, key)em vez de $0 ~ key.


    Como alternativa, sem carregar as palavras-chave no início:

    $ awk -vkeyfile=keywords 'BEGIN {getline key < keyfile } 
          $0 ~ key {print $0; if (!getline key < keyfile) exit;}' data
    foo 1 
    bar 1
    

    Isso deve ser direto.

    • 1

relate perguntas

  • Remova arquivos com os menores sufixos de nome de arquivo

  • Listar arquivos classificados de acordo com a linha de conteúdo específica

  • Como saber antecipadamente se um .zip tem um diretório pai dentro

  • Como encontrar tipos de arquivos específicos e tar-los?

  • du/df e ls relatando diferentes usos de disco

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