Ignorar os 3 primeiros bytes de um arquivo

11

Estou usando o shell do AIX 6.1 ksh.

Eu quero usar um forro para fazer algo assim:

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

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

Alvin SIU
fonte

Respostas:

18

Velha escola - você pode usar dd:

dd if=A_FILE bs=1 skip=3

O arquivo de entrada é A_FILE, o tamanho do bloco é de 1 caractere (byte), pule os primeiros 3 'blocos' (bytes). (Com algumas variantes do ddGNU dd, você pode usar bs=1caqui - e alternativas como bs=1kler em blocos de 1 kilobyte em outras circunstâncias. O ddAIX não suporta isso, ao que parece; a variante BSD (macOS Sierra) não suporta cmas suporta k, m, g, etc.)

Também 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.

Jonathan Leffler
fonte
Obrigado pela ajuda. Os comandos sed e tail funcionam no AIX 6.1. Para o comando dd, ele deve estar dd if=A_FILE bs=1 skip=3no AIX 6.1
Alvin SIU
Você pode querer usar a entrada padrão como gato A_FILE | cauda -c +4 com gnu.
MUY Belgium
14

Em vez de usar, catvocê pode usar tailcomo tal:

tail -c +4 FILE

Isso imprimirá o arquivo inteiro, exceto os 3 primeiros bytes. Consulte man tailpara mais informações.

esquisito
fonte
Não conheço o AIX, mas no Solaris você deve usar /usr/xpg4/bin/tail, pelo menos na minha máquina. Boa dica, no entanto!
BellevueBob
1
@BobDuell É difícil publicar algo que seja compatível com todos os sistemas operacionais.
squiguy
Sim, ele funciona no AIX 6.1
Alvin SIU
@AlvinSIU É bom saber. Ainda bem que pude ajudar.
squiguy
0

Eu precisava fazer recentemente algo semelhante. Eu estava ajudando com um problema de suporte de campo e precisava deixar um técnico ver gráficos em tempo real enquanto fazia 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 fiz foi capturar o tamanho do log antes de começar a processar os dados e, em seguida, entrar em um loop que processaria os dados e cada passagem 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
csherrell
fonte
Se apenas porque estou nesse tipo de humor, e não gosto de codificar contra a saída de ls; você já pensou em usar stat -c'%s' "${IFILE}"esse ls|awkcombo? Ou seja, assumindo coreutils GNU ...
jimbobmcgee
0

Se alguém tem o Python em seu sistema, pode usar um pequeno script python para tirar proveito da seek()função e começar a ler no enésimo byte da seguinte forma:

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

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

Sergiy Kolodyazhnyy
fonte