Pula os primeiros 3 bytes de um arquivo

8

Estou usando o shell do AIX 6.1 ksh.

Eu quero usar um liner para fazer algo assim:

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

Eu quero pular os primeiros 3 bytes da primeira linha; existe uma maneira de fazer isso?

    
por Alvin SIU 24.10.2012 / 17:23

4 respostas

13

Velha escola - você pode usar dd :

dd if=A_FILE bs=1 skip=3

O arquivo de entrada é A_FILE , o tamanho do bloco é 1 caractere (byte), ignore os primeiros 3 'blocos' (bytes). (Com algumas variantes de dd como o GNU dd , você poderia usar bs=1c aqui - e alternativas como bs=1k para ler blocos de 1 kilobyte em outras circunstâncias. O dd no AIX não suporta este , ao que parece, a variante BSD (macOS Sierra) não suporta c mas suporta k , m , g , etc.)

Existem outras maneiras de obter o mesmo resultado:

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

Isso funciona se houver 3 ou mais caracteres na primeira linha.

tail -c +4 A_FILE

E você também pode usar Perl, Python e assim por diante.

    
por 24.10.2012 / 17:38
12

Em vez de usar cat , você pode usar tail como tal:

tail -c +4 FILE

Isso imprimirá todo o arquivo, exceto os primeiros 3 bytes. Consulte man tail para mais informações.

    
por 24.10.2012 / 17:29
0

Eu precisava fazer algo semelhante recentemente. Eu estava ajudando com uma questão de suporte de campo e precisava deixar um técnico ver gráficos em tempo real enquanto eles estavam fazendo alterações. Os dados estão em um log binário que cresce ao longo do dia. Eu tenho um software que pode analisar e plotar os dados dos logs, mas atualmente não é em tempo real. O que eu fiz foi capturar o tamanho do log antes de começar a processar os dados, depois entrar em um loop que processaria os dados e cada passo criaria um novo arquivo com os bytes do arquivo que ainda não haviam sido processados.

#!/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
    
por 04.02.2016 / 04:42
0

Se alguém tem Python em seu sistema, pode-se usar um pequeno script python para aproveitar a função seek() para começar a ler o enésimo byte assim:

#!/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())

E o uso seria assim:

$ ./skip_bytes.py input.txt 3

Note que a contagem de bytes começa em 0 (assim, primeiro byte é na verdade o índice 0), portanto, especificando 3, estamos efetivamente posicionando a leitura para começar em 3 + 1 = 4º byte

    
por 04.02.2017 / 04:59