ファイルの最初の3バイトをスキップする


11

AIX 6.1 kshシェルを使用しています。

私はこのようなことをするために1つのライナーを使いたいです:

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つの「ブロック」(バイト)をスキップします。(ddGNUなどの一部のバリアントではddbs=1cここで使用できますbs=1k。他の状況では、1キロバイトのブロックで読み取るような代替手段がありますdd。AIXではがこれをサポートしていないようです。BSD(macOS Sierra)バリアントはサポートしていませんcしかしんサポートkmg、など)

同じ結果を得る他の方法もあります:

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

そのような猫として標準入力を使いたいかもしれませんA_FILE | gnuでtail -c +4。
MUYベルギー2013

14

使用catする代わりに、次のように使用できますtail

tail -c +4 FILE

これにより、最初の3バイトを除くファイル全体が出力されます。詳細man tailについては、相談してください。


AIXについては知りませんが、Solaris /usr/xpg4/bin/tailでは、少なくとも私のマシンではを使用する必要があります。それでも良いヒント!
BellevueBob

1
@BobDuellすべてのOSと互換性のあるものを投稿するのは難しい。
squiguy 2012年

はい、AIX 6.1で動作します
Alvin SIU 2012年

@AlvinSIU知っておくと良い。お役に立てて嬉しいです。
squiguy 2012年

0

私は最近同様のことをする必要がありました。私はフィールドサポートの問題を支援しており、技術者が変更を加えているときにリアルタイムのプロットを確認する必要がありました。データは1日を通して増加するバイナリログにあります。ログのデータを解析してプロットできるソフトウェアがありますが、現在はリアルタイムではありません。データの処理を開始する前にログのサイズを取得し、データを処理するループに入り、各パスで、まだ処理されていないファイルのバイトで新しいファイルを作成しました。

#!/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ます。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番目のバイトから始まるように読み取り値を効果的に配置しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.