Signor
Signor

Reputation: 563

Bash script for printing Heart shape

i want to write a bash script to echo a shape(heart) that made of strings and draw it in Terminal. like this picture: i find a bash script but it didn't work.

Picture

echo '\x1f\x8b\x08\x00\x95\x10\xe0R\x02\xffSPP\xf0\xc9/KU\x80\x03\x10\x8f\x0bB\xa1c.l\x82dJ\xe0\xb0\x01\xe6\x02\x0cATa.T\xf7\x02\x00\xd9\x91g\x05\xc5\x00\x00\x00'|gunzip

i find above code and tried it, but it didn't work.

Upvotes: 2

Views: 9569

Answers (3)

markp-fuso
markp-fuso

Reputation: 35006

Following up my earlier comment (not sure how to convert a *gz file to a hex string) ...

I found I can do something similar with base64 with the idea being that the base-64 string is going to be easier to work with (ymmv).

Create a file with the desired text 'image', eg:

$ cat heart
   Love          Love
  LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
  LoveLoveLoveLoveLove
    LoveLoveLoveLove
      LoveLoveLove
          Love

Run the file through base64 to generate a base-64 (as opposed to hex==base-16) string representing the contents of the file, eg:

$ base64 heart
ICAgTG92ZSAgICAgICAgICBMb3ZlCiAgTG92ZUxvdmVMb3ZlTG92ZUxvdmUKTG92ZUxvdmVMb3ZlTG92ZUxvdmVMb3ZlCkxvdmVMb3ZlTG92ZUxvdmVMb3ZlTG92ZQpMb3ZlTG92ZUxvdmVMb3ZlTG92ZUxvdmUKICBMb3ZlTG92ZUxvdmVMb3ZlTG92ZQogICAgTG92ZUxvdmVMb3ZlTG92ZQogICAgICBMb3ZlTG92ZUxvdmUKICAgICAgICAgIExvdmUK

At this point you can use following modified command to echo the above string and then pipe it through base64 -d (ie, replace `gunzip), eg:

$ echo "ICAgTG92ZSAgICAgICAgICBMb3ZlCiAgTG92ZUxvdmVMb3ZlTG92ZUxvdmUKTG92ZUxvdmVMb3ZlTG92ZUxvdmVMb3ZlCkxvdmVMb3ZlTG92ZUxvdmVMb3ZlTG92ZQpMb3ZlTG92ZUxvdmVMb3ZlTG92ZUxvdmUKICBMb3ZlTG92ZUxvdmVMb3ZlTG92ZQogICAgTG92ZUxvdmVMb3ZlTG92ZQogICAgICBMb3ZlTG92ZUxvdmUKICAgICAgICAgIExvdmUK=" | base64 -d
   Love          Love
  LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
  LoveLoveLoveLoveLove
    LoveLoveLoveLove
      LoveLoveLove
          Love

NOTE: base64 -d == convert from base-64 to the original contents of the file.


For a smaller string you can gzip the heart file first and then run the *gz file through base64, eg:

$ gzip heart
    => generates file heart.gz
$ base64 heart.gz
H4sICHSiC14AA2hlYXJ0AFNQUPDJL0tVgAMQjwtCoWMubIJkSuCwAeYCDEFUYS409wIAcgvdzcYAAAA=

Then to get back to the image we have to run the steps in reverse:

echo "H4sICHSiC14AA2hlYXJ0AFNQUPDJL0tVgAMQjwtCoWMubIJkSuCwAeYCDEFUYS409wIAcgvdzcYAAAA=" | base64 -d | gunzip
   Love          Love
  LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
  LoveLoveLoveLoveLove
    LoveLoveLoveLove
      LoveLoveLove
          Love

Upvotes: 3

markp-fuso
markp-fuso

Reputation: 35006

Background:

Someone created a text file with the textual image of the heart; let's call the file heart.

Then they (likely) zipped the file with gzip, eg: gzip heart which generated the file heart.gz.

At this point if you ran the file through gunzip and dumped the results to stdout you'd get:

$ gunzip -c heart.gz
   Love          Love
  LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
  LoveLoveLoveLoveLove
    LoveLoveLoveLove
      LoveLoveLove
          Love

You could also generate the same results by cating the heart.gz and then piping the output to gunzip, eg:

$ cat heart.gz | gunzip
   Love          Love
  LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
  LoveLoveLoveLoveLove
    LoveLoveLoveLove
      LoveLoveLove
          Love

Current question:

Instead of uploading the heart.gz file and then requiring the download of said file, the originator (in essence) converted heart.gz to its equivalent string of hex codes. This eliminated the need to upload the heart.gz file.

Now, intead of running the file (heart.gz) through gunzip, the user can echo the hex string to stdout (basically generate the same output as cat heart.gz), which is then piped to gunzip, with the net result that the command you're asking about should generate the image in question:

$ echo '\x1f\x8b\x08\x00\x95\x10\xe0R\x02\xffSPP\xf0\xc9/KU\x80\x03\x10\x8f\x0bB\xa1c.l\x82dJ\xe0\xb0\x01\xe6\x02\x0cATa.T\xf7\x02\x00\xd9\x91g\x05\xc5\x00\x00\x00'|gunzip
   Love          Love
  LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
  LoveLoveLoveLoveLove
    LoveLoveLoveLove
      LoveLoveLove
          Love

NOTE: echo may not work exactly right depending on your version of echo, so you may need to use echo -e (as per Cyrus comment) or replace echo with printf (as per that other guy's answer).

Upvotes: 1

that other guy
that other guy

Reputation: 123570

It's tricky to get exact binary output with echo because implementations differ a lot.

In bash, you can instead do this with printf (other shells vary because \x escapes are not portable):

$ printf '\x1f\x8b\x08\x00\x95\x10\xe0R\x02\xffSPP\xf0\xc9/KU\x80\x03\x10\x8f\x0bB\xa1c.l\x82dJ\xe0\xb0\x01\xe6\x02\x0cATa.T\xf7\x02\x00\xd9\x91g\x05\xc5\x00\x00\x00'|gunzip
   Love          Love
  LoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
LoveLoveLoveLoveLoveLove
  LoveLoveLoveLoveLove
    LoveLoveLoveLove
      LoveLoveLove
          Love$ 

Note that the compressed contents is not linefeed terminated, so the next prompt will appear on top of the heart.

Upvotes: 2

Related Questions