이것은 요청 된 한 줄짜리 솔루션입니다 ( "프로세스 대체"가있는 최근 쉘).
grep -o "ef be ad de" <(hexdump -v -e '/1 "%02x "' infile.bin) | wc -l
"프로세스 대체" <(…)
가 없으면 grep을 필터로 사용하십시오.
hexdump -v -e '/1 "%02x "' infile.bin | grep -o "ef be ad de" | wc -l
아래는 솔루션의 각 부분에 대한 자세한 설명입니다.
16 진수의 바이트 값 :
첫 번째 문제는 해결하기 쉽습니다.
이 \ Xnn 이스케이프 시퀀스는 생선 껍질에서만 작동합니다.
상단 X
을 하단으로 변경하고 x
printf (대부분의 쉘)를 사용하십시오.
$ printf -- '\xef\xbe\xad\xde'
또는 사용하십시오 :
$ /usr/bin/printf -- '\xef\xbe\xad\xde'
'\ x'표현을 구현하지 않기로 선택한 쉘의 경우.
물론 16 진수를 8 진수로 변환하면 거의 모든 쉘에서 작동합니다.
$ "$sh" -c 'printf '\''%b'\'' "$(printf '\''\\0%o'\'' $((0xef)) $((0xbe)) $((0xad)) $((0xde)) )"'
여기서 "$ sh"는 (합리적인) 쉘입니다. 그러나 올바르게 인용하는 것은 매우 어렵습니다.
이진 파일.
가장 강력한 솔루션은 파일과 바이트 시퀀스 (둘 다)를 (new line) 0x0A
또는 (null byte) 와 같은 홀수 문자 값에 문제가없는 인코딩으로 변환하는 것 0x00
입니다. 둘 다 "텍스트 파일"을 처리하도록 설계된 도구를 사용하여 올바르게 관리하기가 매우 어렵습니다.
base64와 같은 변환은 유효한 것으로 보이지만 모든 입력 바이트가 mod 24 (비트) 위치의 첫 번째, 두 번째 또는 세 번째 바이트인지에 따라 최대 3 개의 출력 표현을 가질 수있는 문제를 나타냅니다.
$ echo "abc" | base64
YWJjCg==
$ echo "-abc" | base64
LWFiYwo=
$ echo "--abc" | base64
LS1hYmMK
$ echo "---abc" | base64 # Note that YWJj repeats.
LS0tYWJjCg==
16 진 변환
따라서 가장 강력한 변환은 간단한 HEX 표현과 같이 각 바이트 경계에서 시작하는 변환이어야합니다.
이 도구 중 하나를 사용하여 파일의 16 진 표현으로 파일을 얻을 수 있습니다.
$ 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
이 경우 검색 할 바이트 시퀀스는 이미 16 진입니다.
:
$ var="ef be ad de"
그러나 변형 될 수도 있습니다. 왕복 hex-bin-hex의 예는 다음과 같습니다.
$ echo "ef be ad de" | xxd -p -r | od -vAn -tx1
ef be ad de
검색 문자열은 이진 표현으로 설정 될 수 있습니다. 위에서 제시 한 od, hexdump 또는 xxd의 세 가지 옵션 중 하나가 동일합니다. 일치가 바이트 경계에 있도록 공백을 포함하십시오 (니블 시프트가 허용되지 않음).
$ a="$(printf "\xef\xbe\xad\xde" | hexdump -v -e '/1 "%02x "')"
$ echo "$a"
ef be ad de
이진 파일이 다음과 같은 경우 :
$ 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
그런 다음 간단한 grep 검색은 일치하는 시퀀스 목록을 제공합니다.
$ grep -o "$a" infile.hex | wc -l
2
한 줄?
모두 한 줄로 수행 할 수 있습니다.
$ grep -o "ef be ad de" <(xxd -c 1 -p infile.bin | tr '\n' ' ') | wc -l
예를 들어, 11221122
동일한 파일에서 검색 하려면 다음 두 단계가 필요합니다.
$ a="$(printf '11221122' | hexdump -v -e '/1 "%02x "')"
$ grep -o "$a" <(xxd -c1 -p infile.bin | tr '\n' ' ') | wc -l
4
일치하는 것을 "보려면":
$ 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
버퍼링
grep이 전체 파일을 버퍼링하고 파일이 큰 경우 컴퓨터에 많은 부담을 줄 우려가 있습니다. 이를 위해 버퍼되지 않은 sed 솔루션을 사용할 수 있습니다.
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
첫 번째 sed는 버퍼되지 -u
않고 ( ) 일치하는 문자열 당 스트림에 줄 바꿈을 두 개만 주입하는 데만 사용됩니다. 두 번째 sed
는 일치하는 줄만 인쇄합니다. wc -l은 일치하는 행을 계산합니다.
짧은 줄만 버퍼링합니다. 두 번째 sed에서 일치하는 문자열입니다. 사용되는 리소스가 매우 적어야합니다.
또는 이해하기가 다소 복잡하지만 하나의 sed에서 동일한 아이디어가 있습니다.
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