Odpowiedzi:
Old school - możesz użyć dd
:
dd if=A_FILE bs=1 skip=3
Plik wejściowy ma A_FILE
rozmiar bloku 1 znak (bajt), pomiń pierwsze 3 „bloki” (bajty). (W przypadku niektórych wariantów dd
takich jak GNU dd
, możesz użyć bs=1c
tutaj - a alternatywy lubią bs=1k
czytać w blokach 1 kilobajta w innych okolicznościach. Wydaje się, że dd
w systemie AIX nie obsługuje tego; wariant BSD (macOS Sierra) nie obsługuje c
ale obsługuje k
, m
, g
, itd.)
Istnieją również inne sposoby osiągnięcia tego samego rezultatu:
sed '1s/^...//' A_FILE
Działa to, jeśli w pierwszym wierszu są 3 lub więcej znaków.
tail -c +4 A_FILE
I możesz także używać Perla, Pythona i tak dalej.
Zamiast używać cat
możesz użyć tail
jako takiego:
tail -c +4 FILE
Spowoduje to wydrukowanie całego pliku z wyjątkiem pierwszych 3 bajtów. Skonsultuj się man tail
po więcej informacji.
/usr/xpg4/bin/tail
, przynajmniej na moim komputerze. Niemniej jednak dobra wskazówka!
Musiałem ostatnio zrobić coś podobnego. Pomagałem w problemach z obsługą techniczną i musiałem pozwolić technikowi zobaczyć wykresy w czasie rzeczywistym, gdy wprowadzali zmiany. Dane znajdują się w dzienniku binarnym, który rośnie przez cały dzień. Mam oprogramowanie, które może analizować i drukować dane z dzienników, ale obecnie nie jest to czas rzeczywisty. To, co zrobiłem, to przechwycenie rozmiaru dziennika, zanim zacząłem przetwarzać dane, a następnie przeszedłem do pętli, która przetworzy dane i za każdym razem utworzy nowy plik z bajtami pliku, który nie został jeszcze przetworzony.
#!/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
; czy rozważałeś użycie stat -c'%s' "${IFILE}"
zamiast tego zestawu ls|awk
? To znaczy, zakładając, że GNU coreutils ...
Jeśli ktoś ma Python w swoim systemie, można użyć małego skryptu Python, aby skorzystać z seek()
funkcji, aby rozpocząć czytanie od n-tego bajtu, tak jak:
#!/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())
A użycie byłoby takie:
$ ./skip_bytes.py input.txt 3
Zauważ, że liczba bajtów zaczyna się od 0 (tak więc pierwszy bajt to tak naprawdę indeks 0), dlatego określając 3, efektywnie pozycjonujemy odczyt tak, aby zaczynał się od 3 + 1 = 4 bajt
dd if=A_FILE bs=1 skip=3
w systemie AIX 6.1