Home > Net >  Using regex to get data from a binary stream via the command line
Using regex to get data from a binary stream via the command line

Time:10-27

I have a hacky thing that I'd like to do via the command line because I'd rather not write a program to do it. For some background, the sensor is just sending UDP packets that are simply caught with netcat, nc -ul 192.168.1.1 10000 > output.dat. In this stream, there's occasionally an error. I have a binary data stream from a sensor that will occasionally send an error message as "$ERROR<binary for 129 bytes>".

I would like to come up with some way to parse this error message so that I can just pipe the matches to a file. I believe that the proper regex would be (\$ERROR).{129}, but I've had no luck actually implementing it. I've been simulating the data stream by doing cat file.bin | grep -aEi '(\$ERROR).{129}' but it's not working as I'm getting more characters than the error message.

I'm hoping to use this to watch a stream for the error message and redirect it to a file. Any suggestions on how to fix this regex would be greatly appreciated.

CodePudding user response:

grep is fundamentally a line-oriented tool. If the 129 bytes could contain null bytes or what have you, all bets are off; but maybe try

grep -zEo '$ERROR.{129}' file.bin

where the -z option is non-standard, and says to use null bytes instead of newlines as the delimiter between "lines"; and the -o option says to print only the match, not the entire "line" where the match was found.

The parentheses around $ERROR didn't contribute anything useful, so I took them out.

CodePudding user response:

grep just filters the line where $ERROR can be found. If you want to do some processing on it, you need to go a step further, like using cut, like in this example:

cat file.txt | cut -c 1-10

This only shows the first ten characters of each line of the file.

So, your solution could be:

cat file.bin | grep -aEi '(\$ERROR).{129}' | cut -c 1-10

Obviously, as you file contains binary characters, you might need to use cut -b, for cutting the bytes:

cat file.bin | grep -aEi '(\$ERROR).{129}' | cut -b 1-10

Edit: as commented by tripleee, this can be improved to:

grep -aEi '(\$ERROR).{129}' file.bin | cut -b 1-10
  • Related