Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

330
Visualizações
Cómo encontrar la posición de byte de una línea específica en un archivo

¿Cuál es la forma más rápida de encontrar la posición de byte de una línea específica en un archivo desde la línea de comando?

p.ej

 $ linepos myfile.txt 13 5283

Estoy escribiendo un analizador para un CSV que tiene varios GB de tamaño y, en caso de que el analizador se detenga, me gustaría poder reanudar desde la última posición. El analizador está en Python, pero incluso iterar sobre file.readlines() lleva mucho tiempo, ya que hay millones de filas en el archivo. Me gustaría simplemente hacer file.seek(int(command.getoutput("linepos myfile.txt %i" % lastrow))) , pero no puedo encontrar un comando de shell para hacer esto de manera eficiente.

Editar: Perdón por la confusión, pero estoy buscando una solución que no sea de Python. Ya sé cómo hacer esto desde Python.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Del comentario de @chepner sobre mi otra respuesta:

 position = 0 # or wherever you left off last time try: with open('myfile.txt') as file: file.seek(position) # zero in base case for line in file: position = file.tell() # current seek position in file # process the line except: print 'exception occurred at position {}'.format(position) raise
over 4 years ago · Santiago Trujillo Relatório

0

La iteración sobre un objeto de archivo produce líneas con finales de línea completos intactos. Debería poder simplemente agregar la len a un objeto contador para obtener la posición. Deberá multiplicar según la codificación de caracteres (tamaño de bytes de carácter)

 position = 0 # or wherever you left off last time try: with open('myfile.txt') as file: # don't you go correcting me on naming it file. we don't call file directly anyway! file.seek(position) # zero in base case for line in file: position += len(line) # process the line except: # yes, a naked exception. TWO faux pas in one answer?!? print 'exception occurred at position {}'.format(position) raise # re-raise to see traceback or what have you
over 4 years ago · Santiago Trujillo Relatório

0

Bueno, si tu patrón es simple, este sería simple.

 $ echo -e '#!/bin/bash\necho abracadabra' >/tmp/script $ pattern=bash $ sed -rn "0,/$pattern/ {s/^(.*)$pattern.*$/\1/p ;t exit; p; :exit }" /tmp/script \ | wc -c 8

Como puede ver, esto generará la posición del primer carácter en su patrón, asumiendo que el primer carácter en el archivo tiene el número 1.

NB 1: sed tiene la costumbre de agregar una nueva línea final a la última cadena que analiza, por lo tanto, cuando tomamos una parte de la línea que precede al pattern , el número de bytes en la salida debe ser 7 (cuéntelos → #!/bin/ ), pero lo que realmente cuenta wc -c parece

 $ sed -rn "0,/$pattern/ {s/^(.*)$pattern.*$/\1/p ;t exit; p; :exit }" /tmp/script \ | hexdump -C 00000000 23 21 2f 62 69 6e 2f 0a |#!/bin/.| 00000008

Esto podría ser una fuente potencial de problemas, si estuviera buscando EOF, por ejemplo. No puedo pensar en un caso más apropiado, solo quiero señalarlo.

NB 2: si el patrón contendrá caracteres especiales, sed fallará. Si pudiera proporcionar un ejemplo de lo que está buscando, podría escapar.

NB 3: Esto supone que el pattern es único. Si deja de leer el archivo en una segunda o tercera instancia de pattern , esto no funcionará.


Actualizar. He encontrado una forma más sencilla.

 $ grep -bo bash <<< '#!/bin/bash' 7:bash

Para GNU grep hay dos opciones:

 -b, --byte-offset Print the 0-based byte offset within the input file before each line of output. If -o (--only-matching) is specified, print the offset of the matching part itself.

Sugeriría usar grep, porque si especifica la tecla -F , tratará el patrón como una cadena simple.

 $ grep -F '!@##$@#%%^%&*%^&*(^)((**%%^@#' <<<'!@##$@#%%^%&*%^&*(^)((**%%^@#' !@##$@#%%^%&*%^&*(^)((**%%^@#
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda