Share your knowledge at the LQ Wiki.
 Home Forums HCL Reviews Tutorials Articles Register Search Today's Posts Mark Forums Read
 LinuxQuestions.org [SOLVED] Hex compare in shell
 Linux - Newbie This Linux forum is for members that are new to Linux. Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

 01-07-2013, 10:01 PM #1 nicksu Member   Registered: Dec 2012 Posts: 34 Rep: Hex compare in shell Hi Can anybody show me how to compare Hex number in shell? I define A=`grep log artifact|cut -d":" -f3`,and it echos the A is 0x5a,and how can I do to compare whether it equals 0x5a or not? I tried == and -eq but both in vain. Thank you Last edited by nicksu; 01-07-2013 at 10:05 PM.
 01-08-2013, 08:59 AM #2 Snark1994 Senior Member   Registered: Sep 2010 Location: Wales, UK Distribution: Arch Posts: 1,632 Blog Entries: 3 Rep: '==' should work - '0x5a' is not a byte, it's a string. Code: ```\$ B='\x5a' \$ echo \$B Z \$ A='0x5a' \$ echo \$A 0x5a \$ if [[ \$A == '0x5a' ]]; then echo "Equal"; fi Equal``` Does that answer your question?
01-08-2013, 09:22 PM   #3
nicksu
Member

Registered: Dec 2012
Posts: 34

Original Poster
Rep:
Quote:
 Originally Posted by Snark1994 '==' should work - '0x5a' is not a byte, it's a string. Code: ```\$ B='\x5a' \$ echo \$B Z \$ A='0x5a' \$ echo \$A 0x5a \$ if [[ \$A == '0x5a' ]]; then echo "Equal"; fi Equal``` Does that answer your question?
Hi Sir,when I define the value of A like you do,it is ok.but if I fetch the value from a command,it is wrong again as below:

Code:
```[ssh@localhost hctest]\$ A=0x5a
[ssh@localhost hctest]\$ if [[ \$A == '0x5a' ]];echo compliant;fi
-bash: syntax error near unexpected token `fi'
[ssh@localhost hctest]\$ if [[ \$A == '0x5a' ]]; then echo compliant; fi
compliant
[ssh@localhost hctest]\$ A=`grep -iw port artifact|grep -v ^*|awk -v FS=" " '{print \$3}'`
[ssh@localhost hctest]\$ echo \$A
0x6300
[ssh@localhost hctest]\$ if [[ \$A == '0x6300' ]]; then echo compliant; fi```

 01-09-2013, 04:13 AM #4 Snark1994 Senior Member   Registered: Sep 2010 Location: Wales, UK Distribution: Arch Posts: 1,632 Blog Entries: 3 Rep: Hm, I haven't seen that before. What does Code: `echo \${#A}` say? And is 'artifact' a file? If so, can you post it?
01-09-2013, 04:34 AM   #5
nicksu
Member

Registered: Dec 2012
Posts: 34

Original Poster
Rep:
Quote:
 Originally Posted by Snark1994 Hm, I haven't seen that before. What does Code: `echo \${#A}` say? And is 'artifact' a file? If so, can you post it?
Sir,it shows 7,could you told me why it shows 7? yup,artifct is a regular file,sorry that cannot show it all out,but the line which match my grep shows as below:
Code:
```** Some port to listen on:
Port    REG_DWORD    0x6300```

 01-09-2013, 04:08 PM #6 David the H. Bash Guru   Registered: Jun 2004 Location: Osaka, Japan Distribution: Debian sid + kde 3.5 & 4.4 Posts: 6,823 Rep: Code: `A=`grep -iw port artifact|grep -v ^*|awk -v FS=" " '{print \$3}'`` This is an unnecessary string of greps, when awk can do it all single-handed. Code: `A=\$( awk '/Port.*REG_DWORD/ { print \$3 }' )` Or something similar. (\$(..) is highly recommended over `..`) Is it certain that there will always be only one line that matches though? If anything other than the field you want gets into the output you're not going to get a match. So when debugging code, you should start by echoing your variables, preferably with some kind of brackets around them to make any whitespace visible. Another possibility is the line ending. This looks like the output of a windows registry or somesuch, and if the file has dos-style line endings, the invisible carriage return could be ending up tacked onto the end of the field. Try running it through cat -A: Code: `echo "[\$A]" | cat -A` 1 members found this post helpful.
01-09-2013, 10:23 PM   #7
nicksu
Member

Registered: Dec 2012
Posts: 34

Original Poster
Rep:

Quote:
 Originally Posted by David the H. Code: `A=`grep -iw port artifact|grep -v ^*|awk -v FS=" " '{print \$3}'`` This is an unnecessary string of greps, when awk can do it all single-handed. Code: `A=\$( awk '/Port.*REG_DWORD/ { print \$3 }' )` Or something similar. (\$(..) is highly recommended over `..`) Is it certain that there will always be only one line that matches though? If anything other than the field you want gets into the output you're not going to get a match. So when debugging code, you should start by echoing your variables, preferably with some kind of brackets around them to make any whitespace visible. Another possibility is the line ending. This looks like the output of a windows registry or somesuch, and if the file has dos-style line endings, the invisible carriage return could be ending up tacked onto the end of the field. Try running it through cat -A: Code: `echo "[\$A]" | cat -A`
Thank you Sir,it finially solve my problem,when I used cat -A,it shows a "^M" at the end of the value,but a "\$" in stead in the value which I explicitly define as A="0x6300",it is the difference between Windows and Unix' text format.and after I used the tr -d '\r',the "==" work,and it exactly work.So appreciate for your help.

 01-10-2013, 12:51 AM #8 chrism01 LQ Guru   Registered: Aug 2004 Location: Sydney Distribution: Centos 6.7, Centos 5.10 Posts: 16,644 Rep: Actually for file conversions, you can use the dos2unix & unix2dos cmds http://linux.die.net/man/1/unix2dos
 01-11-2013, 04:40 AM #9 David the H. Bash Guru   Registered: Jun 2004 Location: Osaka, Japan Distribution: Debian sid + kde 3.5 & 4.4 Posts: 6,823 Rep: cat -A displays non-printing ascii characters in caret notation format, except for LF (line feed,\n) line-endings, which are represented with "\$". "^M" is of course the caret notation for CR (carriage return,\r). (If you weren't aware, the dos line format uses CRLF, while unix uses LF only. awk expects unix style, which is why you end up with an extra carriage return at the end of the line.) There are any number of ways to convert between the two, from stand-alone programs like tofrodos, to simple tr, sed, or awk commands, or anything really that can process text. There's really no correct or best way. You could even do it in the shell with a simple parameter substitution. Code: ```A=\${A%.} #removes the final character, no matter what it is shopt -s extquote #uses bash's ascii-style quoting to only target CRs A=\${A%\$'\r'} #safer than the above, but less portable``` In awk you could even simply set the input record separator so that it can handle either input format (the output is unix-style by default). Code: `awk -v RS='\r?\n' '/Port.*REG_DWORD/ { print \$3 }'` Last edited by David the H.; 01-11-2013 at 04:45 AM. Reason: small rewording
 01-11-2013, 10:28 AM #10 theNbomr LQ 5k Club   Registered: Aug 2005 Distribution: OpenSuse, Fedora, Redhat, Debian Posts: 5,396 Blog Entries: 2 Rep: A lot of this thread seems to arise from the misunderstanding of the distinction between the value of a byte and the representation of that value. A byte is eight ordered bits, and has the same value irrespective of how we represent it. The representation commonly reflects the context of usage, but never affects the value. A problem arises when people use terminology like 'Hex number' which is a mixture of terms. A number is a number, and has a value. Its representation may be in many forms, of which one is hex. The problem is that expressing the representation as part of the problem implies that we must treat the data as string/character, since that is the only way to represent data in any radix-specific context. If the data is not string/character data, then expressing the radix is irrelevant. Whenever there is any question about the nature of some data, I find it useful to display the data using od. I prefer to represent the data in hex, since that tends to be context agnostic. Reperesenting it as character/text can lead to confusion, since some characters have particular meanings in some contexts, line-endings like Carriage-returns and Linfeeds in particular. od quickly and unambiguously exposes these, displaying CRs and LFs in hex as 0D and 0A, respectively. I like to use the form Code: `od -tx1 someArbitraryFile` Article #2 of this thread seizes on this concept immediately, but the real problem seems to come down to the use of DOS oriented line terminators. These can be quickly found with od. The problem gets somewhat compounded (and becomes more confounding) when some programming languages silently convert our strings that represent numbers (like here; '0x6300') into integer or floating point scalar variables. It often isn't clear which interpretation a language will make. For instance in article two of this thread, Snark1994 gives the example Code: ```\$ B='\x5a' \$ echo \$B Z \$ A='0x5a' \$ echo \$A 0x5a \$ if [[ \$A == '0x5a' ]]; then echo "Equal"; fi Equal``` This is supposed to demonstrate how bash (or some shell, I presume) makes the interpretation. However in my bash shell (GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu) ), I get Code: ```\$ B='\x5a' \$ echo \$B \x5a``` What's up with that? --- rod.
 01-11-2013, 11:04 AM #11 David the H. Bash Guru   Registered: Jun 2004 Location: Osaka, Japan Distribution: Debian sid + kde 3.5 & 4.4 Posts: 6,823 Rep: the echo command in bash doesn't automatically expand hex values, or any other backslash references, by default. That's what the -e option is for. (The '%b' token in printf also expands them.) But you can also turn expansion on globally with the xpg_echo shell option. Then you can use the -E to disable it locally. Code: ```\$ B='\x5a' \$ echo "\$B" ; echo -e "\$B" ; printf '%b\n' "\$B" \x5a Z Z \$ shopt -s xpg_echo ; echo "\$B" ; echo -E "\$B" Z \x5a``` Another choice is to use the \$'..' quoting mechanism. But you can't use that with variables, since it otherwise acts like a hard-quote. You'd have to use it when setting the variable, and the resulting contents would be the expanded value. Code: ```\$ B=\$'\x5a' \$ echo "\$B" Z``` Some other shells might have different behavior. The POSIX echo specification doesn't define any arguments for it, so its up to the individual shell. Last edited by David the H.; 01-11-2013 at 11:06 AM.
01-12-2013, 03:43 PM   #12
Snark1994
Senior Member

Registered: Sep 2010
Location: Wales, UK
Distribution: Arch
Posts: 1,632
Blog Entries: 3

Rep:
Quote:
 Originally Posted by theNbomr For instance in article two of this thread, Snark1994 gives the example Code: ```\$ B='\x5a' \$ echo \$B Z \$ A='0x5a' \$ echo \$A 0x5a \$ if [[ \$A == '0x5a' ]]; then echo "Equal"; fi Equal``` This is supposed to demonstrate how bash (or some shell, I presume) makes the interpretation. However in my bash shell (GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu) ), I get Code: ```\$ B='\x5a' \$ echo \$B \x5a``` What's up with that? --- rod.
Sorry, I was using zsh, and may well have options set in my .zshrc which change zsh's default behaviour on this issue anyway...

Thanks for the 'od' tip, I often find it frustrating when debugging bash to work out what /exactly/ a variable contains...

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is Off HTML code is Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post discomurder Programming 5 06-11-2011 05:03 PM corteplaneta Programming 8 09-18-2010 01:32 AM 51dunk Linux - Software 6 01-20-2009 07:07 AM mlewis Programming 35 04-10-2008 12:05 PM shashwat.gupta Programming 8 05-24-2006 02:13 AM

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

 Contact Us - Advertising Info - Rules - LQ Merchandise - Donations - Contributing Member - LQ Sitemap -