ข้าม 3 ไบต์แรกของไฟล์


11

ฉันใช้ AIX 6.1 ksh shell

ฉันต้องการใช้สายการบินหนึ่งในการทำสิ่งนี้:

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

ฉันต้องการข้าม 3 ไบต์แรกของบรรทัดแรก มีวิธีทำเช่นนี้หรือไม่?

คำตอบ:


19

โรงเรียนเก่า - คุณสามารถใช้dd:

dd if=A_FILE bs=1 skip=3

ไฟล์อินพุตคือA_FILEขนาดบล็อกคือ 1 อักขระ (ไบต์) ข้าม 3 'บล็อก' (ไบต์) 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 | tail -c +4 กับ gnu
MUY เบลเยี่ยม

15

แทนที่จะใช้catคุณสามารถใช้tailเช่น:

tail -c +4 FILE

สิ่งนี้จะพิมพ์ไฟล์ทั้งหมดยกเว้น 3 ไบต์แรก ปรึกษาman tailข้อมูลเพิ่มเติม


ไม่ทราบเกี่ยวกับ AIX แต่/usr/xpg4/bin/tailอย่างน้อยในSolaris คุณต้องใช้อย่างน้อยในเครื่องของฉัน เคล็ดลับที่ดีอย่างไรก็ตาม!
BellevueBob

1
@BobDuell มันยากที่จะโพสต์สิ่งที่เข้ากันได้กับทุกระบบปฏิบัติการ
squiguy

ใช่ทำงานได้ใน 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

ถ้าเพียงเพราะฉันอยู่ในอารมณ์แบบนั้นและไม่ชอบการเข้ารหัสกับผลลัพธ์ของ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.