Convert binary strings into decimal

I want to process with a bash script a text file that looks like this:

``````ADD    \$05  \$05  \$05
SUBI   \$06  \$06  00011
MUL    \$07  \$07  \$07
JSR    011101
``````

taking the binary numbers (that are always longer than 4 bits) and converting them into their decimal representation.

For the previous example, this is the file I want to end up with:

``````ADD    \$05  \$05  \$05
SUBI   \$06  \$06  3
MUL    \$07  \$07  \$07
JSR    29
``````

I have been exploring `tr` and `sed`, but I think they don't let me work with the matched pattern (to convert it) before the replacement. What approach can I take?

EDIT: with the suggestion of @DopeGothi, and given that I have at most one binary number per line, I can create a temporary file with all the decimal versions of the binary numbers. The issue is that now I need to intercalate them:

Every time I find a binary number in the first file, I replace with the corresponding number in the file with decimals.

• As a start, you can use this to extract and convert the binary numbers: `| grep -oE '[01]+' | awk '{print "ibase=2;obase=A;"\$1}' | bc`. Bear in mind that this has no way of distinguishing whether `10` is decimal, binary, octal, hexadecimal, or any other base. Commented Sep 28, 2018 at 23:44
• but with that grep I am going to lose the rest of the content, no? I am going to read about awk, though. Commented Sep 29, 2018 at 0:36

Try this small `bash` script:

``````while read -a INP; do for i in \${INP[@]}; do [[ "\$i" =~ [^10] ]] || i=\$((2#\$i));  printf "%s\t" "\$i" ; done; printf "\n"; done < file3
SUBI    \$06     \$06     3
MUL     \$07     \$07     \$07
JSR     29
``````

May benefit from some polishing. It reads the file's lines into an array, tests if its elements contain binary digits (0 and 1) only, uses "arithmetic evaluation" with the base 2 `2#` prefix if yes, before it prints

There's probably a more elegant way using Perl's `pack` and `unpack`, but using a combination of string manipulation and `oct`:

``````\$ perl -pe 's/\b[01]+\b/oct "0b" . \$&/ge' file