LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
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

Reply
 
Search this Thread
Old 01-07-2013, 10:01 PM   #1
nicksu
Member
 
Registered: Dec 2012
Posts: 34

Rep: Reputation: Disabled
Question 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.
 
Old 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: Reputation: 345Reputation: 345Reputation: 345Reputation: 345
'==' 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?
 
Old 01-08-2013, 09:22 PM   #3
nicksu
Member
 
Registered: Dec 2012
Posts: 34

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Snark1994 View Post
'==' 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
 
Old 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: Reputation: 345Reputation: 345Reputation: 345Reputation: 345
Hm, I haven't seen that before. What does

Code:
echo ${#A}
say? And is 'artifact' a file? If so, can you post it?
 
Old 01-09-2013, 04:34 AM   #5
nicksu
Member
 
Registered: Dec 2012
Posts: 34

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Snark1994 View Post
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
Appreciate your reply,thank you man!
 
Old 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: Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949
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.
Old 01-09-2013, 10:23 PM   #7
nicksu
Member
 
Registered: Dec 2012
Posts: 34

Original Poster
Rep: Reputation: Disabled
Cool

Quote:
Originally Posted by David the H. View Post
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.
 
Old 01-10-2013, 12:51 AM   #8
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,289

Rep: Reputation: 2034Reputation: 2034Reputation: 2034Reputation: 2034Reputation: 2034Reputation: 2034Reputation: 2034Reputation: 2034Reputation: 2034Reputation: 2034Reputation: 2034
Actually for file conversions, you can use the dos2unix & unix2dos cmds
http://linux.die.net/man/1/unix2dos
 
Old 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: Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949
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
 
Old 01-11-2013, 10:28 AM   #10
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
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.
 
Old 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: Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949
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.
 
Old 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: Reputation: 345Reputation: 345Reputation: 345Reputation: 345
Quote:
Originally Posted by theNbomr View Post
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...
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Replace character with hex value of my choosing from shell cmd line? (Solaris 5, ksh) discomurder Programming 5 06-11-2011 05:03 PM
Shell Script Compare Folders corteplaneta Programming 8 09-18-2010 01:32 AM
Searching software to compare binary files in hex 51dunk Linux - Software 6 01-20-2009 07:07 AM
Hex output of a hex/ascii input string mlewis Programming 35 04-10-2008 12:05 PM
compare files in C shell shashwat.gupta Programming 8 05-24-2006 02:13 AM


All times are GMT -5. The time now is 08:48 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration