Encontre uma palavra antes de encontrar outra

0

Eu quero encontrar a tabela que contém um valor. Eu vejo algumas soluções usando o mysql, mas eu comecei a pensar, como posso fazer isso no linux ?, e eu não tenho nenhuma idéia, mas eu quero saber. Então, os passos seriam: - Encontre uma palavra em um arquivo (mysqldump) - volte para encontrar o nome da tabela (mais ou menos a linha que contém a palavra 'table')

Ele tem um problema adicional, porque quando o grep encontra a palavra ele retorna uma linha enorme, então você precisa cortar de alguma forma.

Minha aproximação mais próxima:

tr , '\n' < database.sql | grep -ne 'str'

Então, talvez eu possa fazer algo como obter as linhas anteriores com head , mas não sei como recursivamente até encontrar 'table' e depois retornar a linha +3 linhas para cima e para baixo.

Para esclarecer minha dúvida. O arquivo contém mais ou menos:

[....]
(line 234) "INSERT INTO table_name ...."
[...]
(line 400) ... str ...
[...]

Deveria ser: tr , '\n' < database.sql para cortar as linhas longas grep -ne 'str' para encontrar o número da linha, no exemplo é 400 então deve começar a procurar no arquivo desta linha para cima para encontrar a outra palavra

tac [start in line 400] | grep -m 1 "INSERT INTO"

tudo em uma linha

ATUALIZAÇÃO Eu tenho uma boa aproximação:

var=$(tr , '\n' < database.sql | grep -m 1 -ne 'str' | cut -f1 -d:) ; head -n$var log.log | grep -m1 -C2 'INSERT INTO'

Eu prefiro um que pode começar na linha x e subir até encontrar o str, mas funciona

    
por oootramas 19.10.2017 / 17:12

3 respostas

0

Sem uma resposta melhor, tomo minha aproximação:

var=$(tr , '\n' < database.sql | grep -m 1 -ne 'str' | cut -f1 -d:) ; head -n$var log.log | grep -m 1 'INSERT INTO'

Eu prefiro um que pode começar na linha x e subir até encontrar o str, mas está funcionando.

    
por 23.10.2017 / 10:02
0

O Grep tem duas boas opções, -A (depois) e -B (antes), então:

tr , '\n' < database.sql | grep -ne -A3 -B3 'str'

retornaria a linha contendo a string que você pesquisou, mais as três linhas acima dela e as três linhas abaixo dela.

Gostaria de responder a pergunta inteira, mas infelizmente não entendo o que você está tentando fazer.

Para cortar a string, você pode usar o comando cut e / ou awk

O AWK é mais complexo, mas um uso simples seria awk {'print $1'}

então:

tr , '\n' < database.sql | grep -ne -A3 -B3 'str' | awk {'print $1'} imprimiria o primeiro arquivado no resultado, onde o campo é qualquer coisa para o primeiro espaço em branco.

e da mesma forma com corte:

tr , '\n' < database.sql | grep -ne -A3 -B3 'str' | cut -f1 -d" "

apenas desta vez -d especifica o delimitador entre campos como espaço em branco. Pode ser o que você quiser, mas apenas um personagem. então -f = campo, -d = delimitador.

Espero que isso ajude

    
por 19.10.2017 / 18:09
0

Respondendo apenas à pergunta atual:

[How can one] recursively till it find 'table' and then return the line +3 lines up and down.

Isso é útil com grep , que tem três opções (uma delas implica as outras duas:

  • -Ax (ou "Depois") mostra as linhas x após uma correspondência de padrões (por exemplo, -A3 ).
  • -Bx (ou "Antes") mostra as linhas x antes de uma correspondência de padrões (por exemplo, -B3 ).
  • -Cx (ou "Contexto") mostra as linhas x antes e após uma correspondência de padrões (por exemplo, -C3 ). -Cx é idêntico a -Ax -Bx .

Então, para pesquisar o arquivo haystack para as três linhas antes e depois de cada needle :

$ grep -C3 'needle' /path/to/haystack

Ou, como a agulha no seu caso é a string table :

$ grep -C3 'table' /path/to/haystack

Mas se table não for conhecido por estar sempre em minúsculas (como mysqldump normalmente usa palavras-chave), talvez você queira fazer uma pesquisa sem distinção entre maiúsculas e minúsculas:

$ grep -i -C3 'table' /path/to/haystack
    
por 19.10.2017 / 18:14