0

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. – DopeGhoti Sep 28 '18 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. – onlycparra Sep 29 '18 at 0:36
1

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
ADD    $05  $05  $05
SUBI   $06  $06  3
MUL    $07  $07  $07
JSR    29

See Converting Binary, Octal, and Hexadecimal Numbers

  • this is black magic, thank you a lot... you made me love Perl. – onlycparra Sep 29 '18 at 7:30
1

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
ADD     $05     $05     $05 
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

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.