0

I have the file ~/dummy_hex.txt containing hex and random string:

\x12\xA1\xF1\xE3somegibberigh

I want to count how many hex values (groups of \x^hex_digit^^hex_digit^) the string above has. In the example above I want the commands to run to return the number 4.

In other words I want to type over my terminal:

command ^file_having hex^

And return the value 4

So far I tried to do that with:

sed 's/[^\x[0-9A-Fa-f][0-9A-Fa-f]]//g' dummy_hex.txt | awk '{ print length }'

But somehow seems to return wrong result because of regex misstype. Can you tell me how to use full PCRE compartible regex with sed in order to do that?

Alternatively I want to count how many hex values my string contains.

Edit 1

An another approach is to count the \x string occurences but that may count any stray \x that may not be followed with a value indicating a hexadimal string.

 sed 's/[^\x]//g' dummy_hex.txt | awk '{ print length }'

Further more I tried to do that with -r option that enables PCRE:

 sed -r 's/^\\x[0-9A-Fa-f][0-9A-Fa-f]]/g' dummy_hex.txt | awk '{ print length }'

But I get the error:

sed: -e expression #1, char 31: unterminated `s' command

4
  • Just for clarification: how many bytes are there in this file?
    – user601
    Commented Dec 29, 2017 at 20:44
  • The wc -c says 30 bytes. Commented Dec 29, 2017 at 20:47
  • 2
    So "hex values" really means "groups of <backslash><x><hex digit><hex digit>". Because there is no such thing as a "hex value."
    – user601
    Commented Dec 29, 2017 at 20:57
  • hop Yes hex value means that Commented Dec 29, 2017 at 20:58

4 Answers 4

2

With a grep that supports Extended Regular Expressions and the -o option:

grep -Eo '\\x[[:xdigit:]]{2}' input | wc -l

To fit the requirement of command filename:

function counthex() {
  grep -Eo '\\x[[:xdigit:]]{2}' "$1" | wc -l
}

As:

counthex input
1
$ cat input
bla\x12\xA1\xF1
\xE3bla
$ perl -nle '$c++ while m/\\x[[:xdigit:]]/g; END { print $c }' input
4
$ 

Basically loop without printing over the input (perldoc perlrun), increment a counter for each match, and then print that count.

1

If you count the characters without hex:

$ sed 's/\([^\]*\)\\x[0-9A-Fa-f][0-9A-Fa-f]/\1/g' dummy_hex.txt | LC_ALL=C wc -c
14

And substract that from the whole file count:

$ <dummy_hex.txt wc -c
30

You could get the count of hex characters (times 4). In one script:

#!/bin/bash
a=$(sed 's/\([^\]*\)\\x[0-9A-Fa-f][0-9A-Fa-f]/\1/g' dummy_hex.txt | wc -c)
b=$(<dummy_hex.txt wc -c )
count=$(( (b-a)/4 ))
echo "$count"

Prints:

$ ./script
4

Remember that wc counts bytes (not locale dependent characters).

0

An alternative solution is to use the installed perl to do that:

perl -lne 'print my $c = () = /\\x[[:xdigit:]]+/' dummy_hex.txt

That offer a quick and easy oneliner in case you do not want to write a script (eg. on a instruction sheet that will contain commands to execute.)

1
  • that's going to produce a per-line tally, not a total count
    – thrig
    Commented Dec 29, 2017 at 21:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .