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

  • Just for clarification: how many bytes are there in this file? – user601 Dec 29 '17 at 20:44
  • The wc -c says 30 bytes. – Dimitrios Desyllas Dec 29 '17 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 Dec 29 '17 at 20:57
  • hop Yes hex value means that – Dimitrios Desyllas Dec 29 '17 at 20:58
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.)

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.