LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   scan binary file for word and print words before and after (https://www.linuxquestions.org/questions/linux-general-1/scan-binary-file-for-word-and-print-words-before-and-after-743701/)

kpachopoulos 07-29-2009 10:09 AM

scan binary file for word and print words before and after
 
Hi,
i'd like to scan a binary file for a given word and in case this word is found, print a number of characters (no distinction made between human readable or not) before and a number of character after. For example 10chars+ MY_WORD +10chars.

I am not quite experienced; should i use awk or grep? Use a pattern like a "..........MY_WORD.........."?

Thanks a lot

unSpawn 07-29-2009 05:51 PM

If SEARCHTERM occupies ${#SEARCHTERM} chars, and if STRING=$(grep /path/to/target -m1 -A1 -B1 -a SEARCHTERM), then CHARSBEFORE=${//SEARCHTERM*/} (and CHARSAFTER=${//*SEARCHTERM/} ), so the offset of CHARSBEFORE would be $[${#CHARSBEFORE}-10], so I think you want to display ${CHARSBEFORE:$[${#CHARSBEFORE}-10]:${#CHARSBEFORE}}. Does that make sense?

kpachopoulos 07-30-2009 03:59 AM

Quote:

Originally Posted by unSpawn (Post 3624800)
If SEARCHTERM occupies ${#SEARCHTERM} chars, and if STRING=$(grep /path/to/target -m1 -A1 -B1 -a SEARCHTERM), then CHARSBEFORE=${//SEARCHTERM*/} (and CHARSAFTER=${//*SEARCHTERM/} ), so the offset of CHARSBEFORE would be $[${#CHARSBEFORE}-10], so I think you want to display ${CHARSBEFORE:$[${#CHARSBEFORE}-10]:${#CHARSBEFORE}}. Does that make sense?

Sorry, have rarely used something like this and i do not get it. It could be more help, if you could explain a little. Thanks a lot.

unSpawn 07-30-2009 05:46 AM

If SEARCHTERM=GNU, then total amount of chars in string is 'echo ${#SEARCHTERM}', and displaying first 2 chars (starts at zero) of it is 'echo ${SEARCHTERM:0:2}'
Take as STRING=$(grep /bin/ls -m1 -A1 -B1 -a GNU), you'll have chars in before and after your SEARCHTERM.
Before is CHARSBEFORE=${//SEARCHTERM*/}.
After is CHARSAFTER=${//*SEARCHTERM/}.
Since you want to display 10 chars starting from the end of the string you need the range to be (total amount of chars minus ten) - (total amount of chars).
When debugging 'set' (as in xve) and 'eval' are your friends:
Code:

eval echo ${#CHARSBEFORE}
eval echo $[${#CHARSBEFORE}-10]
eval echo ${CHARSBEFORE:$[${#CHARSBEFORE}-10]:${#CHARSBEFORE}}

Better?

theNbomr 07-30-2009 10:13 AM

unSpawn seems to be trying to show how grep can be used to display leading and trailing context. While I think his commandline example is broken (should be more like 'grep -m1 -A1 -B1 -a GNU /bin/ls'), it seems that he is grabbing one line of 'text' before and after each matching instance, and then, using some bash text manipulation operators, truncating the leading and trailing context to the desired amount of characters. This probably works, but assumes that the leading and trailing context characters are all on the single preceding and succeeding lines (whatever we mean by 'line' in a binary file).
This points to what I see as a fundamental problem with the whole approach: grep, awk, etc., are text oriented tools, which expect newline delimited text, and binary files simply aren't like that. Moreover, displaying raw binary data rarely makes sense, as the effect will be different depending on the terminal in use, and it's runtime configuration. I would suggest re-evaluating your requirements, and/or considering the use of a tool such as od, possibly in combination with grep or other text processor.
--- rod.

unSpawn 07-30-2009 10:30 AM

I did take his "print a number of characters (no distinction made between human readable or not) before and a number of character after" quite literally. Good advice.


All times are GMT -5. The time now is 11:59 AM.