Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
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:
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:
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.
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.
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).
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
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.
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...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.