Omitir los primeros 3 bytes de un archivo

11

Estoy usando AIX 6.1 ksh shell.

Quiero usar un revestimiento para hacer algo como esto:

cat A_FILE | skip-first-3-bytes-of-the-file

Quiero omitir los primeros 3 bytes de la primera línea; ¿Hay alguna forma de hacer esto?

Alvin SIU
fuente

Respuestas:

18

Old school - podrías usar dd:

dd if=A_FILE bs=1 skip=3

El archivo de entrada es A_FILE, el tamaño del bloque es de 1 carácter (byte), omita los primeros 3 'bloques' (bytes). (Con algunas variantes ddcomo GNU dd, puede usar bs=1caquí, y alternativas como bs=1kleer en bloques de 1 kilobyte en otras circunstancias. ddParece que en AIX no es compatible; la variante BSD (macOS Sierra) no es compatible cpero lo hace de soporte k, m, g, etc.)

También hay otras formas de lograr el mismo resultado:

sed '1s/^...//' A_FILE

Esto funciona si hay 3 o más caracteres en la primera línea.

tail -c +4 A_FILE

Y también puedes usar Perl, Python, etc.

Jonathan Leffler
fuente
Gracias por tu ayuda. Los comandos sed y tail funcionan en AIX 6.1. Para el comando dd, debe estar dd if=A_FILE bs=1 skip=3en AIX 6.1
Alvin SIU
Es posible que desee utilizar la entrada estándar como tal cat A_FILE | cola -c +4 con gnu.
MUY Bélgica
14

En lugar de usar cat, puede usar tailcomo tal:

tail -c +4 FILE

Esto imprimirá todo el archivo, excepto los primeros 3 bytes. Consultar man tailpara más información.

squiguy
fuente
No sé acerca de AIX, pero en Solaris debe usar /usr/xpg4/bin/tail, al menos en mi máquina. Buen consejo, no obstante!
BellevueBob
1
@BobDuell Es difícil publicar algo que sea compatible con todos los sistemas operativos.
Squiguy
Sí, funciona en AIX 6.1
Alvin SIU
@AlvinSIU Es bueno saberlo. Me alegro de poder ayudar.
Squiguy
0

Hace poco necesitaba hacer algo similar. Estaba ayudando con un problema de soporte de campo y necesitaba dejar que un técnico viera diagramas en tiempo real mientras realizaban cambios. Los datos están en un registro binario que crece a lo largo del día. Tengo un software que puede analizar y trazar los datos de los registros, pero actualmente no es en tiempo real. Lo que hice fue capturar el tamaño del registro antes de comenzar a procesar los datos, luego entré en un ciclo que procesaría los datos y cada paso crearía un nuevo archivo con los bytes del archivo que aún no se habían procesado.

#!/usr/bin/env bash

# I named this little script hackjob.sh
# The purpose of this is to process an input file and load the results into
# a database. The file is constantly being update, so this runs in a loop
# and every pass it creates a new temp file with bytes that have not yet been
# processed.  It runs about 15 seconds behind real time so it's
# pseudo real time.  This will eventually be replaced by a real time
# queue based version, but this does work and surprisingly well actually.

set -x

# Current data in YYYYMMDD fomat
DATE=`date +%Y%m%d`

INPUT_PATH=/path/to/my/data
IFILE1=${INPUT_PATH}/${DATE}_my_input_file.dat

OUTPUT_PATH=/tmp
OFILE1=${OUTPUT_PATH}/${DATE}_my_input_file.dat

# Capture the size of the original file
SIZE1=`ls -l ${IFILE1} | awk '{print $5}'`

# Copy the original file to /tmp
cp ${IFILE1} ${OFILE1}

while :
do
    sleep 5

    # process_my_data.py ${OFILE1}
    rm ${OFILE1}
    # Copy IFILE1 to OFILE1 minus skipping the amount of data already processed
    dd skip=${SIZE1} bs=1 if=${IFILE1} of=${OFILE1}
    # Update the size of the input file
    SIZE1=`ls -l ${IFILE1} | awk '{print $5}'`

    echo

    DATE=`date +%Y%m%d`

done
csherrell
fuente
Aunque solo sea porque estoy de ese tipo de humor, y no me gusta codificar contra la salida de ls; ¿Has considerado usar en stat -c'%s' "${IFILE}"lugar de ese ls|awkcombo? Es decir, suponiendo que GNU coreutils ...
jimbobmcgee
0

Si uno tiene Python en su sistema, puede usar un pequeño script de Python para aprovechar la seek()función para comenzar a leer en el enésimo byte de la siguiente manera:

#!/usr/bin/env python3
import sys
with open(sys.argv[1],'rb') as fd:
    fd.seek(int(sys.argv[2]))
    for line in fd:
        print(line.decode().strip())

Y el uso sería así:

$ ./skip_bytes.py input.txt 3

Tenga en cuenta que el recuento de bytes comienza en 0 (por lo tanto, el primer byte es en realidad el índice 0), por lo tanto, al especificar 3, estamos posicionando efectivamente la lectura para comenzar en 3 + 1 = 4to byte

Sergiy Kolodyazhnyy
fuente