Überspringen Sie die ersten 3 Bytes einer Datei

10

Ich benutze AIX 6.1 ksh Shell.

Ich möchte einen Liner verwenden, um so etwas zu tun:

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

Ich möchte die ersten 3 Bytes der ersten Zeile überspringen. Gibt es eine Möglichkeit, dies zu tun?

Alvin SIU
quelle

Antworten:

17

Alte Schule - Sie könnten verwenden dd:

dd if=A_FILE bs=1 skip=3

Die Eingabedatei ist A_FILE, die Blockgröße ist 1 Zeichen (Byte), überspringen Sie die ersten 3 'Blöcke' (Bytes). (Mit einigen Varianten ddwie GNU ddkönnen Sie bs=1chier verwenden - und Alternativen bs=1k, die unter anderen Umständen gerne Blöcke von 1 Kilobyte einlesen. Unter ddAIX wird dies anscheinend nicht unterstützt; die BSD-Variante (macOS Sierra) unterstützt dies nicht cunterstützt jedoch k, m, g, etc.)

Es gibt auch andere Möglichkeiten, um das gleiche Ergebnis zu erzielen:

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

Dies funktioniert, wenn sich in der ersten Zeile 3 oder mehr Zeichen befinden.

tail -c +4 A_FILE

Und Sie könnten auch Perl, Python und so weiter verwenden.

Jonathan Leffler
quelle
Danke für Ihre Hilfe. Sowohl der sed- als auch der tail-Befehl funktionieren in AIX 6.1. Für den Befehl dd sollte es dd if=A_FILE bs=1 skip=3in AIX 6.1
Alvin SIU
Möglicherweise möchten Sie die Standardeingabe als solche verwenden. Cat A_FILE | Schwanz -c +4 mit Gnu.
MUY Belgien
14

Anstatt zu verwenden cat, können Sie tailals solches verwenden:

tail -c +4 FILE

Dadurch wird die gesamte Datei mit Ausnahme der ersten 3 Bytes ausgedruckt. Konsultieren Sie man tailfür weitere Informationen.

squiguy
quelle
Ich weiß nichts über AIX, aber unter Solaris müssen Sie es /usr/xpg4/bin/tailzumindest auf meinem Computer verwenden. Trotzdem guter Tipp!
BellevueBob
1
@ BobDuell Es ist schwierig, etwas zu veröffentlichen, das mit jedem Betriebssystem kompatibel ist.
Squiguy
Ja, es funktioniert in AIX 6.1
Alvin SIU
@AlvinSIU Gut zu wissen. Froh, dass ich helfen konnte.
Squiguy
0

Ich musste kürzlich etwas Ähnliches tun. Ich half bei einem Support-Problem vor Ort und musste einen Techniker Echtzeit-Diagramme anzeigen lassen, während er Änderungen vornahm. Die Daten befinden sich in einem binären Protokoll, das im Laufe des Tages wächst. Ich habe eine Software, die die Daten aus Protokollen analysieren und zeichnen kann, aber es ist derzeit nicht in Echtzeit. Ich habe die Größe des Protokolls erfasst, bevor ich mit der Verarbeitung der Daten begonnen habe, und bin dann in eine Schleife gegangen, in der die Daten verarbeitet werden. Bei jedem Durchgang wird eine neue Datei mit den Bytes der Datei erstellt, die noch nicht verarbeitet wurden.

#!/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
quelle
Wenn nur, weil ich in dieser Stimmung bin und nicht gerne gegen die Ausgabe von codiere ls; Haben Sie darüber nachgedacht, stat -c'%s' "${IFILE}"anstelle dieser ls|awkKombination zu verwenden? Das heißt, unter der Annahme von GNU Coreutils ...
jimbobmcgee
0

Wenn man Python auf seinem System hat, kann man ein kleines Python-Skript verwenden, um die seek()Funktion zu nutzen, um beim n-ten Byte wie folgt mit dem Lesen zu beginnen:

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

Und die Nutzung wäre so:

$ ./skip_bytes.py input.txt 3

Beachten Sie, dass die Byteanzahl bei 0 beginnt (das erste Byte ist also tatsächlich der Index 0). Wenn Sie also 3 angeben, positionieren wir den Messwert effektiv so, dass er bei 3 + 1 = 4. Byte beginnt

Sergiy Kolodyazhnyy
quelle