Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

324
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda