私はAIX 6.1 kshシェルを使用しています。
ライナーを使って次のことをしたいと思います。
cat A_FILE | skip-first-3-bytes-of-the-file
最初の行の最初の3バイトをスキップしたいと思います。これを行う方法はありますか?
答え1
オールドスクール - 以下を使用できますdd
。
dd if=A_FILE bs=1 skip=3
入力ファイルは、A_FILE
ブロックサイズは1文字(バイト)で、最初の3つの「チャンク」(バイト)をスキップします。 (dd
GNUなどの一部のバリアントではここで使用dd
でき、他の場合は1KBチャンクで読むbs=1c
などの代替も使用できます。この機能はAIXではサポートされていないようです。macOS Sierra(BSD)バリアントはサポートされていません。サポートしていませんが、などはサポートしています。)bs=1k
dd
c
k
m
g
同じ結果を得る別の方法もあります。
sed '1s/^...//' A_FILE
この方法は、最初の行に3文字以上の文字がある場合に機能します。
tail -c +4 A_FILE
Perl、Pythonなどを使用することもできます。
答え2
cat
使用する代わりにtail
:
tail -c +4 FILE
これにより、最初の3バイトを除くファイル全体が印刷されます。より多くの情報を要求してくださいman tail
。
答え3
seek()
システムにPythonがある場合は、小さなPythonスクリプトを使用して、次のように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番目のバイトから始まるように効果的に配置されます。
答え4
私は最近同様のことをしなければなりませんでした。私は現場サポートの問題を支援していますが、技術者が変更が適用されたらリアルタイムの図面を表示できるようにする必要があります。データは一日中増加するバイナリログにあります。ログデータを解析して表示できるソフトウェアがありますが、現在は機能しません。私がすることは、データ処理を開始する前にログサイズをキャプチャしてからデータを処理するループを入力することです。各パスは、まだ処理されていないファイルのバイトで新しいファイルを生成します。
#!/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