Emacs: Abra um buffer com todas as linhas entre as linhas X a Y de um arquivo enorme

10

No mesmo espírito dessa outra pergunta: cat line X para linha Y em um arquivo enorme :

Existe uma maneira de abrir o no Emacs (e mostrar em um buffer) um determinado conjunto de linhas (por exemplo, todas as linhas entre a linha X e Y ) de um arquivo de texto enorme?

Por exemplo Abra e mostre em um buffer todas as linhas entre as linhas 57890000 e 57890010 do arquivo huge.txt

Atualização: Estou interessado em uma solução que, pelo menos, pode abrir as linhas em somente leitura (apenas para fins de exibição), embora seria ótimo se eu também pudesse editar as linhas (e salvar no arquivo original).

    
por Amelio Vazquez-Reina 08.09.2012 / 01:38

3 respostas

7

Se você quiser abrir o arquivo inteiro (o que requer), mas mostrar apenas parte dele na janela do editor, use narrowing . Selecione a parte do buffer em que você deseja trabalhar e pressione C-x n n ( narrow-to-region ). Diga “sim” se você receber um aviso sobre um comando desativado. Pressione C-x n w ( widen ) para ver o buffer inteiro novamente. Se você salvar o buffer, o arquivo completo é selecionado: todos os dados ainda estão lá, estreitando apenas restringe o que você vê.

Se você quiser ver uma parte de um arquivo, você pode inseri-lo no buffer atual com shell-command com um argumento de prefixo ( M-1 M-! ); execute o comando apropriado para extrair as linhas desejadas , eg <huge.txt tail -n +57890001 | head -n 11 .

Há também uma função Lisp insert-file-contents o que pode levar um intervalo de bytes. Você pode invocá-lo com M-: ( eval-expression ):

(insert-file-contents "huge.txt" nil 456789000 456791000)

Observe que você pode entrar no limite de tamanho inteiro (dependente de versão e plataforma, verificar o valor de most-positive-fixnum ).

Em teoria, seria possível escrever um modo Emacs que carregasse e salvasse partes de arquivos de forma transparente, conforme necessário (embora o limite de tamanhos inteiros tornasse impossível o uso de deslocamentos reais de arquivos em máquinas de 32 bits). O único esforço nessa direção que eu conheço é VLF (link GitHub aqui ).

    
por 08.09.2012 / 15:53
1

Você pode achar útil essa combinação perl e elisp . Ele permite que você canalize dados para um buffer. Invocações subseqüentes usando o mesmo nome de buffer anexarão as novas linhas ao mesmo buffer.

Você pode "editar" o buffer , mas a edição não reflete de forma alguma na fonte (que é um pipe ) ... Ele não mostra qualquer número de linha, embora você possa ajustar a entrada para incluir um prefixo numerado para cada linha.

from=50000000
  to=50000010
<file_50 head -n "$to" | tail -n +"$from" | e-sink.pl

No buffer:

<<<<< start: 2012-09-09T01:39:49
1000000
VSjU K97X5Z dFcc ZZd2OqQ PzbnphT
yQBTt LOic Ks sPXrq tty oy
dA8 SD BvO daZ KFPr44X
X0m3BI eR4go YjFp7e vbJr3oe Y0OGgH3 uPfz yfq59
we rm L9iD ugcJBND daS

7pO lwUFzNE HPlPW fmPZ vpRs Rx EFeHaFM
b0 1B ncr Db324 vwO Un34R
HDZS wq9zg W013 5JGly
kAfP QPpjjyh pXMAw I1 CGKDc23 qCBnP
<<<<<   end: 0.630s

Ou com números de linha adicionados:

from=50000000
  to=50000010
<file_50 head -n "$to" | tail -n +"$from" | nl -v$from -ba -w${#to} | e-sink.pl

No buffer:

<<<<< start: 2012-09-09T01:53:44
50000000    1000000
50000001    VSjU K97X5Z dFcc ZZd2OqQ PzbnphT
50000002    yQBTt LOic Ks sPXrq tty oy
50000003    dA8 SD BvO daZ KFPr44X
50000004    X0m3BI eR4go YjFp7e vbJr3oe Y0OGgH3 uPfz yfq59
50000005    we rm L9iD ugcJBND daS
50000006    
50000007    7pO lwUFzNE HPlPW fmPZ vpRs Rx EFeHaFM
50000008    b0 1B ncr Db324 vwO Un34R
50000009    HDZS wq9zg W013 5JGly
50000010    kAfP QPpjjyh pXMAw I1 CGKDc23 qCBnP
<<<<<   end: 0.768s

Encontrei isso em um StackOverflow Q / A

    
por 08.09.2012 / 18:02
1

Você pode fazer isso com Exibir arquivos grandes , um modo secundário do emacs desenvolvido exatamente para esse caso.

    
por 28.05.2014 / 10:13