Retorna / transforma e retorna o padrão com nulos

0

Estou usando o grep / sed para analisar um grande arquivo binário cheio de nulos para alguns dados específicos. Isso está em um ambiente Windows usando o gnuwin32.

Supondo que eu tivesse alguns para retornar alguns dados de um arquivo binário que se parecesse com isso (representação hexadecimal):

42 9D E1 0A 01 FF FF FF FF FF FF FF 7F 00 FE FF FF 0A 01 E1 0A 01 C0 0B 00 4D 00
00 9C E1 0A 01 2C 41 38 B4 15 FB 49 00 4D 00 41 00 48 00 4F 00 53 00 54 00 31 00
32 00 33 00 2E 00 73 00 75 00 62 00 2E 00 64 00 6F 00 6D 00 61 00 69 00 6E 00 2E
00 73 00 74 00 61 00 2E 00 6F 00 72 00 67 00 2E 00 61 00 75

Mas apenas correspondendo a essa parte do acima:

49 00 4D 00 41 00 48 00 4F 00 53 00 54 00 31 00 32 00 33

Como exatamente eu faria isso usando grep e / ou sed? A presença de nulos faz algumas coisas ruins para o grep, especialmente porque eu realmente preciso retornar os dados como parte de um analisador de arquivos automatizado.

O grep abaixo chega perto de fazer o que eu quero:

grep -Prino ".{0,100}I
sed -rn "/\I\x00M\x00A\x00H\x00O\x00S\x00T\x001\x002\x003/p" "D:\cruft\Hxma.txt"
0M
42 9D E1 0A 01 FF FF FF FF FF FF FF 7F 00 FE FF FF 0A 01 E1 0A 01 C0 0B 00 4D 00
00 9C E1 0A 01 2C 41 38 B4 15 FB 49 00 4D 00 41 00 48 00 4F 00 53 00 54 00 31 00
32 00 33 00 2E 00 73 00 75 00 62 00 2E 00 64 00 6F 00 6D 00 61 00 69 00 6E 00 2E
00 73 00 74 00 61 00 2E 00 6F 00 72 00 67 00 2E 00 61 00 75
0A
49 00 4D 00 41 00 48 00 4F 00 53 00 54 00 31 00 32 00 33
0H
grep -Prino ".{0,100}I
sed -rn "/\I\x00M\x00A\x00H\x00O\x00S\x00T\x001\x002\x003/p" "D:\cruft\Hxma.txt"
0M%pre%0A%pre%0H%pre%0O%pre%0S%pre%0T%pre%01%pre%02%pre%03.{0,100}" "d:\dhcp.mdb"
0O%pre%0S%pre%0T%pre%01%pre%02%pre%03.{0,100}" "d:\dhcp.mdb"

No entanto, ele apenas retorna "Arquivo binário d: \ dhcp.mdb corresponde" em vez do padrão correspondente, provavelmente devido aos valores nulos. Se isso funcionasse, uma vez que eu tivesse 100 caracteres para qualquer um dos lados, eu usaria esse subconjunto para corresponder ao endereço IP (que segue um formato greppable) e ao nome de domínio (que sempre termina com 3 nulos)

Como é um arquivo de banco de dados, eu provavelmente poderia usar um método diferente, como interagir com o banco de dados, mas sinto que estou muito próximo desse método.

Usando Sed, posso ver dados de retorno de um arquivo muito menor em que colei alguns dados relevantes:

%pre%

Mas não sei como devolver 100 caracteres antes e 100 caracteres após a partida, como no grep acima, e quando o executo no banco de dados de 12MB, ele não retorna nada (tirar a opção silenciosa, ele imprime o espaço padrão mostra que ele está ficando ~ 10KB, aparentemente, desistindo)

Alguém sabe como posso continuar resolvendo isso? Devo acrescentar que o formato real dos dados retornados não é muito importante, desde que nenhum dado seja perdido (além dos nulos, eu não preciso deles).

Se isso ajudar, o formato real dos dados de texto que eu quero corresponder parece ser unicode de 2 bytes, embora alguns dos dados precisem retornar junto com a correspondência (ou seja, os primeiros 4 bytes que são um pouco -endian IP address) não está em unicode.

    
por Bruno 26.09.2014 / 05:26

1 resposta

0

Você está dizendo ao grep o que procurar. O conceito de que você não sabe o que você acabou de dizer ao grep para procurar é estranho e eu não o sigo. O propósito do grep é procurar um padrão que você dê a ele; não encontrar uma string que você já conhece a localização. Eu acho que você precisa definir com mais clareza o pedaço desse quebra-cabeça que está perdendo.

Além disso, a maioria dos bancos de dados possui ferramentas de linha de comando. Mesmo que o MS não faça boas ferramentas para seus bancos de dados, existe um pacote chamado ferramentas do MDB que permitirá que você realmente use o SQL para procure o DB. Esta é certamente uma maneira melhor de realizar o que você está tentando fazer aqui.

Por último, se você realmente quisesse pesquisar um binário para strings usando o grep, eu ALTAMENTE sugeriria usar a ferramenta strings no pacote binutils . Isso filtrará o caractere não imprimível antes de pesquisar os dados. Ele também pode imprimir offsets úteis (que é o que você normalmente deseja nessa situação). Aqui está uma amostra de como isso ficaria (isso irá procurar no binário do grep por quaisquer strings que contenham a palavra 'obsoleto'):

strings -a -t x /bin/grep|grep deprecated

Como você pode ver, isso será muito menos propenso a erros. Eu não verifiquei a velocidade disso, mas tenho certeza que seria altamente dependente do conteúdo binário de qualquer maneira.

Atualizar

Apenas percebi que você está trabalhando no Windows. O Systernals faz uma versão do string.exe , que é bastante semelhante ao programa de strings do Linux.

strings.exe -a -o C:\GnuWin\bin\grep.exe|grep deprecated

Além disso, você pode tentar o Jackcess para obter uma ferramenta MDB de linha de comando que funcionará com qualquer sistema operacional com suporte a JVM.

    
por 26.09.2014 / 06:40