Você encontrou um bug no bash, do tipo. É um bug conhecido com uma correção conhecida.
Os programas representam um deslocamento em um arquivo como uma variável em algum tipo inteiro com um tamanho finito. Antigamente, todos usavam int
para praticamente tudo, e o tipo int
estava limitado a 32 bits, incluindo o bit de sinal, para que pudesse armazenar valores de -2147483648 a 2147483647. Atualmente existem diferentes digite nomes para coisas diferentes , incluindo off_t
para um deslocamento em um arquivo.
Por padrão, off_t
é um tipo de 32 bits em uma plataforma de 32 bits (permitindo até 2 GB) e um tipo de 64 bits em uma plataforma de 64 bits (permitindo até 8EB). No entanto, é comum compilar programas com a opção LARGEFILE, que alterna o tipo off_t
para 64 bits e faz o programa chamar implementações adequadas de funções como lseek
.
Parece que você está executando bash em uma plataforma de 32 bits e seu binário bash não é compilado com suporte a arquivos grandes. Agora, quando você lê uma linha de um arquivo normal, o bash usa um buffer interno para ler caracteres em lotes para desempenho (para mais detalhes, veja a fonte em builtins/read.def
). Quando a linha estiver completa, o bash chama lseek
para rebobinar o deslocamento do arquivo de volta para a posição do final da linha, no caso de algum outro programa se importar com a posição naquele arquivo. A chamada para lseek
ocorre na função zsyncfc
em lib/sh/zread.c
.
Eu não li a fonte com muitos detalhes, mas suponho que algo não está acontecendo suavemente no ponto de transição quando o deslocamento absoluto é negativo. Então o bash acaba lendo os offsets errados quando ele recarrega o buffer, depois de passar da marca de 2GB.
Se minha conclusão está errada e seu bash está, de fato, sendo executado em uma plataforma de 64 bits ou compilado com suporte a largefile, isso é definitivamente um bug. Por favor, denuncie para sua distribuição ou upstream .
Um shell não é a ferramenta certa para processar arquivos tão grandes assim mesmo. Vai ser lento. Use sed, se possível, caso contrário, awk.