String chars to ASCII decimals inside terminal

Discussion in 'Mac Programming' started by hakonandersson, Jun 15, 2013.

  1. hakonandersson macrumors newbie

    May 28, 2013
    Hi all,

    Many thanks for any help you can offer me :) I'm not a programmer, however am building a workflow which, in part, I need to convert all the characters of 3 strings (50-60 chars in length, e.g. "Santa Claus - I love Christmas") to ASCII decimals and save this output to file (each file containing 1 character of the string as ASCII decimal, e.g. 'A' as 65).

    There are many online converters, and I've found a tutorial on how to build a converter within xcode ( - however, I am unsure how to go about integrating this into my workflow so I could pipe a string into 'X' inside terminal, and it would then perform the conversion and file save, or at least the conversion and save each decimal as variables so I could then write the variables to file using terminal..

    Do you have any recommendations where I could start, or any links to prior work where I could slot in a solution into my workflow? It's imperative that this can be performed inside a piped terminal command.

    Many thanks for your time,
  2. subsonix macrumors 68040

    Feb 2, 2008
    You could try something like this. Echo is added just to have some input to show how it works.

    echo "Hello World" | od -t d1 | awk '{i = $1; $1 = ""; print $0}'
    awk is added to skip the first column in od which shows an offset value.
  3. ytk macrumors regular

    Jul 8, 2010
    So just making sure I have this straight. You want to split a string out to a series of numbered files, each one having a single decimal ASCII value of the string? So a string of ten characters would create ten files?

    Here's a Ruby program to do that:

    #!/usr/bin/env ruby
    class String
      unless defined? ord # For 1.8.7/1.9+ compatibility
        def ord
    output_path = ARGV[0] || "."
    while input_string = STDIN.gets
      filename = input_string.gsub(/ /, "_").gsub(/[^A-Za-z_]/, "")[0..49]
      input_string.split("").each_with_index do |char, i|"#{File.expand_path output_path}/#{filename}.#{(i+1).to_s.rjust(input_string.size.to_s.size, "0")}", "w") do |f|
          f << char.ord
    Save it to a file, and you can pipe your string into it to do what you need. It will automatically create a series of files named based on the inputted strings (one set of files per line), numbered from 1 to the size of the string. An optional argument to the program will specify the output directory (defaults to the current directory if not specified).

    Hope that does what you need!
  4. hakonandersson, Jun 15, 2013
    Last edited: Jun 15, 2013

    hakonandersson thread starter macrumors newbie

    May 28, 2013
    Gentlemen (or ladies?, I'm making assumptions!!),

    Where can I donate to your weekly beer fund? :)

    Thank you both for your input, both will help me reach my goals. The ruby script will work as I've requested, perfect. Just so I have further options, in regards to the first terminal command, can I have the OD output the values seperated by comma's and not with spaces?


    echo "Bugs Bunny" | od -t d1 | awk '{i = $1; $1 = ""; print $0}' > /Users/hakonandersson/Desktop/test.txt

    outputs " 66 117 103 115 32 66 117 110 110 121 10"

    is it possible for me to output " 66,117,103,115,32,66,117,110,110,121,10"

    Btw, that "10" character at the end, is that some sort of terminating character? end of string?

    cheers guys,

    EDIT: I guess I could just then pipe the OD output into another string formatting command which a) deleted the first space character, then b) replaced all remaining spaces with commas?
  5. chown33 macrumors 604

    Aug 9, 2009
    Sailing beyond the sunset

    I suggest waiting until you actually need these "further options". We'll still be here.

    The Ruby script is, as you say, "perfect". So I propose not writing anything new until after the Ruby script has failed. Then you can come back, explain what happened, describe exactly what needs fixing, and then someone can answer.

    There's little point (but a definite cost) in writing and testing code just so you can have an option you may not need. Wait till it's needed. It's not going on a space probe or a submarine. Revision and refinement when and as needed is possible.
  6. hakonandersson thread starter macrumors newbie

    May 28, 2013
    Hi Chown33,

    Thanks for the feedback - definately learning the pitfalls and hurdles - I think I'm finally getting somewhere.

    In order to have more control and breakup my workflow, I'm trying with subsonix approach first since this is, systematically, the cleaner approach. The ruby script kindly provided will work well if I confirm my output does need to be broken down char by char. I've cobbled together a series of commands (bottom of post) which almost delivers me a string formatted to my requirements (code below). One issue I have, however, is still with the OD command.

    If I do this :

    HAMBP:~ hakonandersson$ echo "Santa Claus - We love christmas" | od -t d1

    i get...

    0000000 83 97 110 116 97 32 67 108 97 117 115 32 45 32 87 101
    0000020 32 108 111 118 101 32 99 104 114 105 115 116 109 97 115 10

    The issue here is, the below series of commands needs to trim the working ascii decimals down to one line only. So I've got a 'head' command in there which prints only the first line... however, as you can see above, it seems the OD command likes to print the string to multiple lines...

    Is there a way I can get OD just to print the ascii decimals all to one long line, regardless of how many characters there will be (I will not know how many characters the original string will be)..

    Thanks for your help!

    My cobbled together series of commands which format the string, works fine...
    read track_name < "/Volumes/RAMDISK/track_name.txt"

    echo ${track_name} | od -t d1 | awk '{i = $1; $1 = ""; print $0}' > /Volumes/RAMDISK/track_name_ascii_1.txt

    sed '1s/^.//' /Volumes/RAMDISK/track_name_ascii_1.txt > /Volumes/RAMDISK/track_name_ascii_2.txt

    head -1 /Volumes/RAMDISK/track_name_ascii_2.txt > /Volumes/RAMDISK/track_name_ascii_3.txt

    tr -s '[:blank:]' ',' < /Volumes/RAMDISK/track_name_ascii_3.txt > /Volumes/RAMDISK/track_name_ascii_final.txt
  7. hakonandersson thread starter macrumors newbie

    May 28, 2013
    I see that I can use the -w command in OD to define the width, e.g.

    echo "Santa Claus - We love christmas" | od -w32 -t d1
    od: illegal option -- w

    However, I keep getting the illegal option as above.. All over the internet however, this appears to be the correct syntax and way to define the number of bytes per line..

    Any ideas? Thanks guys.. Just so you know, this is not a on-the-job knowledge plunder - this is a personal project.

  8. ytk macrumors regular

    Jul 8, 2010
    I'm totally confused now as to what you're trying to do. If you just want to convert your string to ASCII decimals separated by a comma (or whatever), you can use this one-liner:

    echo "Hello there" | ruby -nle 'puts $_.unpack("c*").join(",")'
    Just replace the , with whatever you want your delimiter to be.
  9. hakonandersson thread starter macrumors newbie

    May 28, 2013
    Hi there ytk,

    You're absolutely right - I didn't know what I wanted until I saw it.. this works perfectly and as it seems, matches the syntax required by the program I'm feeding the output to.

    Many many thanks for your time, and everyone else's time here. If you have any preferred online causes you like to donate to - let me know and I'll put a small donation towards the cause - you've helped me a lot.

  10. chown33 macrumors 604

    Aug 9, 2009
    Sailing beyond the sunset
    Where did you see a -w option (Note: not "command")? Post the complete URL.

    When asking about command-lines, it clarifies things if you identify your exact OS version (e.g. 10.8.4). Different OS versions have different versions of commands, which may have different options or capabilities. The same applies for things other than command-lines. For example, there are slightly different capabilities in Automator in different OS versions, too.

    The OS X 'od' command has no -w option. See its man page:

    Man page found by googling:
    os x man page od
  11. ytk macrumors regular

    Jul 8, 2010
    That's generous of you, but I'm just happy to help. I'm sort of wondering what exactly it is you're doing, though...
  12. hakonandersson thread starter macrumors newbie

    May 28, 2013
    Hey Chown33,

    Here is a link to where I saw a 'working example' of the width option (scroll down to Point 10)

    Various other sites just are a copy/paste of the man, and mention the width option also. I'm suprised actually, I've read 'od' is as old as the hills and thought it odd that the version offered in osx 10.8 has dropped functionality which appears to have been offered since the mid 1980's :)

    And, thanks for the link to the 'getting answers'... Next time I'll be utterly concise and to the point, with code and requirements upfront.



    To sooth your curiosity, I'll run you through the broad workflow.. :)

    I have an application on my macbook which is rather closed off (no API's), but on-screen has a number of text elements which I want to be displayed on my ipad. I need the text on the ipad to refresh every 2 seconds or so...

    With no way to directly connect to the macbook app and take the text, I've hacked together a little Automator script which basically

    1. takes a screenshot of the osx application
    2. runs that screenshot through multiple crops to cut out everything except the required text (in png format)
    3. pipe those png's into 'gocr' to capture the text in the png as actual text
    4. take that text, then convert it to ascii in a particular format the ipad app understands
    5. send that to the ipad using another terminal tool (osc)
    6. inside the ipad app, I'm performing an arraytostring function to turn the ascii dec's back to strings

    The reason why I need to go to ascii dec's is because the ipad app has little in the way of string handling and modification, but has rather good vector array handling/modification... so it's better to work with the arrays if you want to 'join' strings or compare them (as arrays) first, then only turn them back to strings in the end..

    So there you go.. conceptually I had everything on the table in the first 5 minutes, but then I thought 'ok crap, how do I actually put this into play'.. :)

    Thx all.
  13. subsonix macrumors 68040

    Feb 2, 2008
    od itself does not have an option to do that and I guess you could add further things to the pipeline to clean it up to your liking. But you could replace od with hexdump which allows you to add a format string to give control of the output.

    If you also want to get rid of the new line that echo produces you can use printf, also with a format string. The following should do what you want I think.

    printf "%s" "Bugs Bunny" | hexdump -v -e '1/1 "%d" ", "' | sed 's/, $//'
    In the end sed is added to get rid of the last ", " separator since the format string add it as a suffix to each number in the output.
  14. chown33 macrumors 604

    Aug 9, 2009
    Sailing beyond the sunset
    The title of that page is Linux OD Command. But OS X isn't Linux.

    Some of OS X's commands come from the Linux line, but many don't. There are Unix and Unix-like commands going back much farther than Linux.

    The commands can have different lineages. Just because a -w option gets added in one lineage doesn't mean it appears in all others. And all options of a command don't necessarily appear at the same time.
  15. subsonix macrumors 68040

    Feb 2, 2008
    There are rules, and respect for standards (specifically POSIX). One should not simply add flags left and right, because it breaks compatibility (as we have just witnessed) and creates fragmentation. :cool:

    Also this! ;)

Share This Page