Пропустить первые 3 байта файла

11

Я использую оболочку AIX 6.1 ksh.

Я хочу использовать один лайнер, чтобы сделать что-то вроде этого:

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

Я хочу пропустить первые 3 байта первой строки; Есть ли способ сделать это?

Элвин Сиу
источник

Ответы:

18

Старая школа - вы можете использовать dd:

dd if=A_FILE bs=1 skip=3

Входной файл имеет A_FILEразмер блока 1 символ (байт), пропустите первые 3 «блока» (байта). (С некоторыми вариантами, ddтакими как GNU dd, вы могли бы использовать bs=1cздесь - и альтернативы, такие как bs=1kчтение в блоках 1 килобайт в других обстоятельствах. ddПохоже, что в AIX это не поддерживается; вариант BSD (macOS Sierra) не поддерживает cно поддерживает k, m, gи т.д.)

Есть и другие способы достижения того же результата:

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

Это работает, если в первой строке 3 или более символов.

tail -c +4 A_FILE

И вы могли бы использовать Perl, Python и так далее.

Джонатан Леффлер
источник
Спасибо за вашу помощь. Обе команды sed и tail работают в AIX 6.1. Для команды dd она должна быть dd if=A_FILE bs=1 skip=3в AIX 6.1
Alvin SIU
Вы можете использовать стандартный ввод как таковой. Cat A_FILE | хвост -c +4 с гну.
MUY Бельгия
14

Вместо использования catвы можете использовать tailкак таковой:

tail -c +4 FILE

Это распечатает весь файл за исключением первых 3 байтов. Проконсультируйтесь man tailдля получения дополнительной информации.

squiguy
источник
Не знаю об AIX, но в Solaris вы должны использовать /usr/xpg4/bin/tail, по крайней мере, на моей машине. Хороший совет, тем не менее!
BellevueBob
1
@BobDuell Трудно опубликовать что-то совместимое с любой ОС.
'10
Да, это работает в AIX 6.1
Alvin SIU
@AlvinSIU Полезно знать. Рад, что смог помочь.
squiguy
0

Мне нужно было недавно сделать что-то подобное. Я помогал с проблемой полевой поддержки, и мне нужно было, чтобы техник видел графики в реальном времени, когда они вносили изменения. Данные находятся в двоичном журнале, который растет в течение дня. У меня есть программное обеспечение, которое может анализировать и выводить данные из журналов, но в настоящее время это не в режиме реального времени. Что я сделал, так это зафиксировал размер журнала до того, как начал обрабатывать данные, затем пошел в цикл, который обрабатывал бы данные, и каждый проход создавал новый файл с байтами файла, который еще не был обработан.

#!/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
источник
Хотя бы потому, что я нахожусь в таком настроении и не люблю кодировать против выходных данных ls; Вы решили использовать stat -c'%s' "${IFILE}"вместо этого ls|awkкомбо? То есть, предполагая, что GNU coreutils ...
jimbobmcgee
0

Если у вас есть Python в их системе, можно использовать маленький скрипт на Python, чтобы воспользоваться seek()функцией, чтобы начать чтение с n-го байта следующим образом:

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

И использование будет так:

$ ./skip_bytes.py input.txt 3

Обратите внимание, что количество байтов начинается с 0 (таким образом, первый байт на самом деле является индексом 0), поэтому, указав 3, мы эффективно позиционируем чтение, чтобы начать с 3 + 1 = 4-й байт.

Сергей Колодяжный
источник