Respostas:
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 dd
GNU dd
, você pode usar bs=1c
aqui - e alternativas como bs=1k
ler em blocos de 1 kilobyte em outras circunstâncias. O dd
AIX não suporta isso, ao que parece; a variante BSD (macOS Sierra) não suporta c
mas 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.
Em vez de usar, cat
você pode usar tail
como tal:
tail -c +4 FILE
Isso imprimirá o arquivo inteiro, exceto os 3 primeiros bytes. Consulte man tail
para mais informações.
/usr/xpg4/bin/tail
, pelo menos na minha máquina. Boa dica, no entanto!
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
ls
; você já pensou em usar stat -c'%s' "${IFILE}"
esse ls|awk
combo? Ou seja, assumindo coreutils GNU ...
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
dd if=A_FILE bs=1 skip=3
no AIX 6.1