Ignorer les 3 premiers octets d'un fichier

11

J'utilise le shell AIX 6.1 ksh.

Je veux utiliser une doublure pour faire quelque chose comme ça:

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

Je veux sauter les 3 premiers octets de la première ligne; Y a-t-il un moyen de faire cela?

Alvin SIU
la source

Réponses:

18

Old school - vous pouvez utiliser dd:

dd if=A_FILE bs=1 skip=3

Le fichier d'entrée est A_FILE, la taille du bloc est de 1 caractère (octet), ignorez les 3 premiers «blocs» (octets). (Avec certaines variantes de ddGNU dd, vous pouvez utiliser bs=1cici - et des alternatives comme bs=1klire en blocs de 1 kilo-octet dans d'autres circonstances. Le ddsur AIX ne le prend pas en charge, il semble; la variante BSD (macOS Sierra) ne prend pas en charge cmais prend en charge k, m, g, etc.)

Il existe également d'autres façons d'obtenir le même résultat:

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

Cela fonctionne s'il y a 3 caractères ou plus sur la première ligne.

tail -c +4 A_FILE

Et vous pouvez aussi utiliser Perl, Python et ainsi de suite.

Jonathan Leffler
la source
Merci de votre aide. Les commandes sed et tail fonctionnent dans AIX 6.1. Pour la commande dd, elle devrait être dd if=A_FILE bs=1 skip=3dans AIX 6.1
Alvin SIU
Vous voudrez peut-être utiliser l'entrée standard comme tel chat A_FILE | queue -c +4 avec gnu.
MUY Belgique
14

Au lieu d'utiliser, catvous pouvez utiliser tailcomme tel:

tail -c +4 FILE

Cela imprimera tout le fichier à l'exception des 3 premiers octets. Consultez man tailpour plus d'informations.

squiguy
la source
Je ne sais pas pour AIX, mais sur Solaris vous devez utiliser /usr/xpg4/bin/tail, au moins sur ma machine. Bon conseil quand même!
BellevueBob
1
@BobDuell Il est difficile de publier quelque chose qui est compatible avec tous les systèmes d'exploitation.
squiguy
Oui, cela fonctionne dans AIX 6.1
Alvin SIU
@AlvinSIU Bon à savoir. Heureux d'avoir pu aider.
squiguy
0

Je devais récemment faire quelque chose de similaire. J'aidais avec un problème de support sur le terrain et je devais laisser un technicien voir les tracés en temps réel pendant qu'ils apportaient des modifications. Les données sont dans un journal binaire qui croît tout au long de la journée. J'ai un logiciel qui peut analyser et tracer les données des journaux, mais ce n'est actuellement pas en temps réel. J'ai capturé la taille du journal avant de commencer à traiter les données, puis je suis entré dans une boucle qui traiterait les données et chaque passage créerait un nouveau fichier avec les octets du fichier qui n'avaient pas encore été traités.

#!/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
la source
Ne serait-ce que parce que je suis dans ce genre d'humeur et que je n'aime pas coder contre la sortie de ls; avez-vous envisagé d'utiliser à la stat -c'%s' "${IFILE}"place de ce ls|awkcombo? Autrement dit, en supposant que GNU coreutils ...
jimbobmcgee
0

Si l'on a Python sur son système, on peut utiliser un petit script python pour profiter de la seek()fonction pour commencer la lecture au nième octet comme ceci:

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

Et l'utilisation serait comme ça:

$ ./skip_bytes.py input.txt 3

Notez que le nombre d'octets commence à 0 (donc le premier octet est en fait l'index 0), donc en spécifiant 3, nous positionnons effectivement la lecture pour commencer à 3 + 1 = 4e octet

Sergiy Kolodyazhnyy
la source