Bu istenen tek astarlı çözümdür ("proses ikamesi" olan son mermiler için):
grep -o "ef be ad de" <(hexdump -v -e '/1 "%02x "' infile.bin) | wc -l
"İşlem ikamesi" <(…)
yoksa, filtre olarak grep kullanın:
hexdump -v -e '/1 "%02x "' infile.bin | grep -o "ef be ad de" | wc -l
Aşağıda, çözümün her bir bölümünün ayrıntılı açıklaması verilmiştir.
Onaltılık sayılardan gelen bayt değerleri:
İlk sorununuzu çözmek kolaydır:
Bu \ Xnn kaçış dizileri sadece balık kabuğunda çalışır.
Üst kısmı X
aşağıya doğru değiştirin x
ve printf kullanın (çoğu kabuk için):
$ printf -- '\xef\xbe\xad\xde'
Ya da kullan:
$ /usr/bin/printf -- '\xef\xbe\xad\xde'
'\ X' temsilini uygulamamayı seçen mermiler için.
Tabii ki, hex'i octal'a çevirmek herhangi bir kabuk üzerinde (neredeyse) çalışacaktır:
$ "$sh" -c 'printf '\''%b'\'' "$(printf '\''\\0%o'\'' $((0xef)) $((0xbe)) $((0xad)) $((0xde)) )"'
"$ Sh" herhangi (makul) bir kabuk olduğunda. Ancak doğru bir şekilde alıntı yapmak oldukça zordur.
İkili dosyalar.
En sağlam çözüm, dosyayı ve bayt dizisini (her ikisini), (yeni satır) 0x0A
veya (boş bayt) gibi tek karakter değerleriyle hiçbir sorunu olmayan bazı kodlamalara dönüştürmektir 0x00
. Her ikisinin de "metin dosyalarını" işlemek için tasarlanmış ve uyarlanmış araçlarla doğru şekilde yönetilmesi oldukça zordur.
Base64 gibi bir dönüşüm geçerli gibi görünebilir, ancak mod 24 (bit) konumunun birinci, ikinci veya üçüncü bayt olmasına bağlı olarak her giriş baytının üç çıkış gösterimine sahip olabileceği sorununu sunar.
$ echo "abc" | base64
YWJjCg==
$ echo "-abc" | base64
LWFiYwo=
$ echo "--abc" | base64
LS1hYmMK
$ echo "---abc" | base64 # Note that YWJj repeats.
LS0tYWJjCg==
Hex dönüşümü.
Bu nedenle en sağlam dönüşüm, basit HEX temsili gibi her bayt sınırında başlayan bir dönüşüm olmalıdır.
Bu araçlardan herhangi biriyle dosyanın onaltılı temsilini içeren bir dosya alabiliriz:
$ od -vAn -tx1 infile.bin | tr -d '\n' > infile.hex
$ hexdump -v -e '/1 "%02x "' infile.bin > infile.hex
$ xxd -c1 -p infile.bin | tr '\n' ' ' > infile.hex
Bu durumda aranacak bayt dizisi zaten onaltılıdır.
:
$ var="ef be ad de"
Ama aynı zamanda dönüştürülebilir. Bir gidiş-dönüş hex-bin-hex örneği aşağıdadır:
$ echo "ef be ad de" | xxd -p -r | od -vAn -tx1
ef be ad de
Arama dizgisi ikili gösterimden ayarlanabilir. Yukarıda sunulan üç seçenekten herhangi biri od, hexdump veya xxd eşdeğerdir. Maçın bayt sınırlarında olduğundan emin olmak için boşluk eklediğinizden emin olun (kemirmek kaydırmaya izin verilmez):
$ a="$(printf "\xef\xbe\xad\xde" | hexdump -v -e '/1 "%02x "')"
$ echo "$a"
ef be ad de
İkili dosya şöyle görünürse:
$ cat infile.bin | xxd
00000000: 5468 6973 2069 7320 efbe adde 2061 2074 This is .... a t
00000010: 6573 7420 0aef bead de0a 6f66 2069 6e70 est ......of inp
00000020: 7574 200a dead beef 0a66 726f 6d20 6120 ut ......from a
00000030: 6269 0a6e 6172 7920 6669 6c65 2e0a 3131 bi.nary file..11
00000040: 3232 3131 3232 3131 3232 3131 3232 3131 2211221122112211
00000050: 3232 3131 3232 3131 3232 3131 3232 3131 2211221122112211
00000060: 3232 0a
Ardından, basit bir grep araması eşleşen dizilerin listesini verecektir:
$ grep -o "$a" infile.hex | wc -l
2
Tek çizgi?
Her şey bir satırda yapılabilir:
$ grep -o "ef be ad de" <(xxd -c 1 -p infile.bin | tr '\n' ' ') | wc -l
Örneğin 11221122
, aynı dosyada arama yapmak için şu iki adım gerekir:
$ a="$(printf '11221122' | hexdump -v -e '/1 "%02x "')"
$ grep -o "$a" <(xxd -c1 -p infile.bin | tr '\n' ' ') | wc -l
4
Eşleşmeleri "görmek" için:
$ grep -o "$a" <(xxd -c1 -p infile.bin | tr '\n' ' ')
3131323231313232
3131323231313232
3131323231313232
3131323231313232
$ grep "$a" <(xxd -c1 -p infile.bin | tr '\n' ' ')
… 0a 3131323231313232313132323131323231313232313132323131323231313232 313132320a
tamponlama
Grep'in tüm dosyayı arabelleğe alacağına dair bir endişe var ve dosya büyükse, bilgisayar için ağır bir yük oluşturuyor. Bunun için tamponlanmamış bir sed çözümü kullanabiliriz:
a='ef be ad de'
hexdump -v -e '/1 "%02x "' infile.bin |
sed -ue 's/\('"$a"'\)/\n\1\n/g' |
sed -n '/^'"$a"'$/p' |
wc -l
İlk sed arabelleğe alınmış ( -u
) değildir ve yalnızca eşleşen dize başına akışa iki yeni satır enjekte etmek için kullanılır. İkincisi sed
sadece (kısa) eşleşen çizgileri basacaktır. Wc -l eşleşen satırları sayar.
Bu sadece bazı kısa satırları tamponlayacaktır. İkinci sed'deki eşleşen dize (ler). Kullanılan kaynaklarda bu oldukça düşük olmalıdır.
Ya da, anlaşılması biraz daha karmaşık, ama aynı fikir bir sed'de:
a='ef be ad de'
hexdump -v -e '/1 "%02x "' infile.bin |
sed -u '/\n/P;//!s/'"$a"'/\n&\n/;D' |
wc -l
grep -o