CẬP NHẬT (với nhận thức muộn màng): ... Câu hỏi / câu trả lời này (câu trả lời của tôi) khiến tôi nghĩ về con chó cứ đuổi theo xe .. Một ngày nọ, cuối cùng, anh ta đuổi kịp xe .. Được rồi, anh ta đã bắt được nó, nhưng anh ta thực sự không thể làm gì nhiều với nó ... Điều này anser 'bắt' các chuỗi, nhưng sau đó bạn không thể làm gì nhiều với chúng, nếu chúng đã nhúng null-byte ... (vì vậy câu trả lời +1 lớn cho Gilles .. một ngôn ngữ khác có thể theo thứ tự ở đây.)
dd
đọc bất kỳ và tất cả dữ liệu ... Nó chắc chắn sẽ không bực bội ở mức 0 dưới dạng "độ dài" ... nhưng nếu bạn có \ x00 ở bất kỳ đâu trong dữ liệu của mình, bạn sẽ cần sáng tạo cách bạn xử lý nó; dd
không có biểu tượng nào với nó, nhưng tập lệnh shell của bạn sẽ có vấn đề (nhưng nó phụ thuộc vào những gì bạn muốn làm với dữ liệu) ... Về cơ bản, sau đây xuất từng "chuỗi dữ liệu", thành một tệp có một vạch chia giữa mỗi strin ...
btw: Bạn nói "ký tự" và tôi giả sử bạn có nghĩa là "byte" ...
nhưng từ "ký tự" đã trở nên mơ hồ trong những ngày này của UNICODE, trong đó chỉ có bộ ký tự ASCII 7 bit sử dụng một byte cho mỗi ký tự ... Và ngay cả trong hệ thống Unicode, số byte thay đổi tùy theo phương pháp mã hóa ký tự , vd. UTF-8, UTF-16, v.v.
Đây là một tập lệnh đơn giản để làm nổi bật sự khác biệt giữa "ký tự" văn bản và byte.
STRING="௵"
echo "CHAR count is: ${#STRING}"
echo "BYTE count is: $(echo -n $STRING|wc -c)"
# CHAR count is: 1
# BYTE count is: 3 # UTF-8 ecnoded (on my system)
Nếu ký tự độ dài của bạn dài 1 byte và biểu thị độ dài byte , thì tập lệnh này sẽ thực hiện thủ thuật, ngay cả khi dữ liệu chứa các ký tự Unicode ... dd
chỉ nhìn thấy các byte bất kể cài đặt ngôn ngữ địa phương nào ...
Tập lệnh này sử dụng dd
để đọc tệp nhị phân và xuất ra các chuỗi được phân tách bằng dấu chia "====" ... Xem tập lệnh tiếp theo để biết dữ liệu thử nghiệm
#
div="================================="; echo $div
((skip=0)) # read bytes at this offset
while ( true ) ; do
# Get the "length" byte
((count=1)) # count of bytes to read
dd if=binfile bs=1 skip=$skip count=$count of=datalen 2>/dev/null
(( $(<datalen wc -c) != count )) && { echo "INFO: End-Of-File" ; break ; }
strlen=$((0x$(<datalen xxd -ps))) # xxd is shipped as part of the 'vim-common' package
#
# Get the string
((count=strlen)) # count of bytes to read
((skip+=1)) # read bytes from and including this offset
dd if=binfile bs=1 skip=$skip count=$count of=dataline 2>/dev/null
ddgetct=$(<dataline wc -c)
(( ddgetct != count )) && { echo "ERROR: Line data length ($ddgetct) is not as expected ($count) at offset ($skip)." ; break ; }
echo -e "\n$div" >>dataline # add a newline for TEST PURPOSES ONLY...
cat dataline
#
((skip=skip+count)) # read bytes from and including this offset
done
#
echo
lối ra
Tập lệnh này xây dựng dữ liệu thử nghiệm bao gồm tiền tố 3 byte trên mỗi dòng ...
Tiền tố là một ký tự Unicode được mã hóa UTF-8 duy nhất ...
# build test data
# ===============
prefix="௵" # prefix all non-zero length strings will this obvious 3-byte marker.
prelen=$(echo -n $prefix|wc -c)
printf \\0 > binfile # force 1st string to be zero-length (to check zero-length logic)
( lmax=3 # line max ... the last on is set to 255-length (to check max-length logic)
for ((i=1;i<=$lmax;i++)) ; do # add prefixed random length lines
suflen=$(numrandom /0..$((255-prelen))/) # random length string (min of 3 bytes)
((i==lmax)) && ((suflen=255-prelen)) # make last line full length (255)
strlen=$((prelen+suflen))
printf \\$((($strlen/64)*100+$strlen%64/8*10+$strlen%8))"$prefix"
for ((j=0;j<suflen;j++)) ; do
byteval=$(numrandom /9,10,32..126/) # output only printabls ASCII characters
printf \\$((($byteval/64)*100+$byteval%64/8*10+$byteval%8))
done
# 'numrandom' is from package 'num-utils"
done
) >>binfile
#