Como extrair bytes do meio de um arquivo?

1

Estamos analisando alguns arquivos EDI grandes que não contêm CR / LF. No entanto, eles têm ~ ( til ) como um delimitador de segmentos.

Eu estou tentando extrair o registro de controle para o arquivo e os últimos bytes do meu arquivo de 120 MB são parecidos com isto:

~REF*1L*0711882~SE*62300*39093~GE*1*500001242~IEA*1*500001241~

Existe apenas um registro de controle no arquivo e sempre começa com ~SE .

Existe uma maneira fácil de usar o recorte padrão do Unix, awk , grep , etc. ferramentas para cortar este arquivo para obter o segmento SE * 62300 * 39093, além de converter o ~ em CRLF e seguir as últimas três linhas do arquivo?

Aviso:
Eu não sou um guru Unix, então a resposta pode ser óbvia para um usuário experiente. Além disso, não tenho controle sobre o formato do arquivo.

    
por Noah 31.01.2013 / 21:01

3 respostas

3

Você pode fazer isso com:% tr "~" "\n" < edi_file | tail -20 | grep ^SE

O tr tr aproxima todos os tildes a novas linhas. (Esses são representados por um \ n).

A saída é então alimentada para a cauda, que descarta todas as últimas 20 linhas.

Você provavelmente pode ajustar isso, dependendo do que deseja pesquisar. Sem ele, todo o arquivo é alimentado para o grep, o que provavelmente requer muito mais recursos do que a cauda. Se você tem uma versão específica da cauda que suporta a exibição de parte de um arquivo com base em bytes, em vez de linhas, você pode até usar esse passo mais cedo.

Eu não escolhi essa opção porque sua postagem é marcada como genérica unix ao invés de linux moderno com ferramentas GNU atualizadas e extensões específicas do GNU .

Finalmente, grep filtra as linhas finais para aquelas que contêm SE, e o carret ( ^ ) certifica-se de que está no início em uma linha. (Evitar coisas como ~ foooo SE foobarquz ~ SE foram parte disso ~ boobar ~ para mostrar duas linhas).

    
por 01.02.2013 / 18:23
4

Embora eu possa ver que não quero modificar o arquivo original, você pode fazer a tradução em um pipe. Dessa forma, você não está modificando os dados, mas ainda assim obtém o benefício (nos termos do utilitário Unix) de transformar ~ em fim de linha.

Isso deve funcionar:

cat ding | tr "~" "\n" | tail -3

Não é a coisa mais eficiente no universo, mas mesmo em um arquivo de 120 MB, isso não deve ser um grande problema para ser executado.

Observe que as aspas nos dois conjuntos não são opcionais - tanto ~ quanto \n serão interpretadas pelo shell se você soltar as aspas.

    
por 31.01.2013 / 21:17
2

Será ineficiente em arquivos grandes para tr primeiro, porque você realmente deseja dados do final e tr processará os dados que serão descartados.

Use tac para ler o arquivo ao contrário, então pegue as 20 primeiras linhas (do verso, então, na verdade a última), inverta novamente para obter a ordem original, agora grep :

tac -s~ edi_file | head -n 20 | tac | grep ^SE

Lembre-se de que você não pode seek() um canal!

    
por 01.02.2013 / 20:02

Tags