0

So let's say i have a file with both binary numbers (0,1) and some other numbers in base 10 (0-9):

010... 10567
011... 23678
...

etc.

the above example isn't actually their exact representation but that's beside the point (and only to illustrate this specific case)

I already know how to grep for only "numbers" in a file/output:

grep '[0-9]*'

Using this:

grep '[0-1]*'

Would highlight/select the 1 and 0 that are part of the base10 numbers.

So I'm unsure how to do the same thing for just binary numbers (0,1). So that the example output would only show the binary numbers (binaries are always in the same column).

Any ways to do this?

6
  • 2
    The problem is that for example, 10 is a binary as well a base 10 number. Do you have another criteria in your file that can help distinguish them? Jan 13 '21 at 16:41
  • well, i guess there always a space between the binary(1,0) and the base10/decimal numbers in the example output...would that help? :) @schrodigerscatcuriosity Jan 13 '21 at 16:42
  • 1
    Are the binaries always in the same column then? Jan 13 '21 at 16:48
  • yep :) they are. @schrodigerscatcuriosity Jan 13 '21 at 16:49
  • 4
    Then you don't need grep unless you want specific binaries. Let's say they are in the first column, so you use awk: awk '{ print $1 }' file. Jan 13 '21 at 16:52
4

The following would look at the data in column col, and whenever the data in that column consists of only ones and zeros, that data is printed.

The col column number is given on the command line (I'm using 1 as its value here):

awk -v col=1 '$col ~ /^[01]+$/ { print $col }' file

If you know that your binary numbers always start with a zero, then you may change the expression from ^[01]+$ to ^0[01]*$ (a zero followed by any number of ones and/or zeros). If you additionally know that your binary numbers are always three digits long, use ^0[01][01]$ or ^0[01]{2}$.

Testing:

$ cat file
010 10567
011 23678
030 10567
012 23678
$ awk -v col=1 '$col ~ /^[01]+$/ { print $col }' file
010
011
2

A simpler solution is:

grep -E "\<[01]+\>" filename

\< and \> are word boundaries and the regular expression matches 1 or more occurrences of 01.

You may also use awk to match in just the specified column; using awk, if the binary string is in column 1, you can do the following:

awk 'match($1,/\<[01]+\>/) {print $1}'
3
  • 1
    That would erroneously identify decimal numbers consisting only of a leading one and zero or more ones and zeros (for example 10)
    – roaima
    Jan 13 '21 at 17:16
  • That way, any binary number can be considered a decimal as well. And I suggested to restrict to a column, if necessary.
    – unxnut
    Jan 13 '21 at 18:42
  • Perhaps you could demonstrate how to "use awk to match"
    – roaima
    Jan 13 '21 at 19:02
0

As i found out a better solution (credit to @Inian in the comment section of the earlier post for the solution)

grep -E '\b[01]+\b'

which seems to work on actual binary-only input. It does not falsely match binary numbers that are part of a decimal/other numbers too.

So:

echo "10198865" |  grep -E '\b[01]+\b'

output nothing, but:

echo "101010" |  grep -E '\b[01]+\b'

does.

-1

Sounds like you need to search for some number of consecutive 0 and 1 that don't have any other digits directly before or after. So, something like this, for at least 3 consecutive 0 and 1 (untested):

[^2-9][01]{3,}[^2-9]

Edit: As mentioned in the comments, this also matches something like '210001'.

7
  • 1
    Or get ripgrep. It's much better than grep and has a modern regex engine (the one in grep is from the stone age).
    – Roger Dahl
    Jan 13 '21 at 16:50
  • 1
    this seems to work even better :o @Inian Thanks! Jan 13 '21 at 16:54
  • 1
    This would identify a011b as a binary number. It also does not restrict the match to a single column.
    – Kusalananda
    Jan 13 '21 at 17:49
  • 1
    That would erroneously identify decimal numbers consisting only of a leading one and zero or more ones and zeros (for example 10000)
    – roaima
    Jan 13 '21 at 18:18
  • 1
    That also matches on the 10001 in 3100014 for instance Jan 14 '21 at 19:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.