DEV Community

Peter Benjamin (they/them)
Peter Benjamin (they/them)

Posted on

Search For GIFs Without Leaving Your Terminal

terminal

Problem

Have you ever wanted to search for GIFs from the terminal?

Perhaps it's just me, but I do a lot in the terminal, from writing code and debugging programs to searching and browsing the web (via ddgr + !bangs).

When I am reviewing Pull Requests (via gh or glab), I often like to post a funny GIF as a comment when I'm approving the PR (hopefully to leave the collaborator with a smile).

Initially, I did this by going to a site, like giphy.com, then searching for a GIF, then several clicks later, I got a GIF URL that I can copy/paste into the terminal. This obviously broke my workflow.

Solution

The second iteration of this used ddgr, a command-line interface for DuckDuckGo. Using the !gif or !giphy bang (e.g. ddgr --no-prompt '!gif yay') did save me a few steps as it takes me right to Giphy's search results where I can get a GIF URL with a few clicks. However, because this still requires a browser, it doesn't work for all the times I work on remote development servers (e.g. GCP Always Free Compute Engine, Raspberry Pi ...etc).

I needed a different solution that was completely in the terminal.

I couldn't find a dependency-free* CLI utility that really suit my needs. So, I decided to write a dependency-free CLI utility that allows you to search for GIFs from giphy.com and return a URL.

And it fits in a tweet.

Here it is:

$ giphy() { [ -z "${1}" ] && return 1 || curl -fsSL https://giphy.com/search/${1} | rg -oP "(?<=gifs: ).*?(?=,$)" | jq ".[$(echo $(( $RANDOM % 25 )) )] | .images.original.url" | tr -d '"'; };
Enter fullscreen mode Exit fullscreen mode

Let's break it down:

  • [ -z "${1}" ] && return 1 || ... : this is kind of a ternary operation in Bash. If the 1st argument is empty, then return non-zero exit code, otherwise ...
  • curl -fsSL https://giphy.com/search/${1}: this is pretty straight-forward. We use curl to query the site.
  • rg -oP "(?<=gifs: ).*?(?=,$)": this uses Positive Lookbehind (?<=...) and Positive Lookahead (?=...) Regular Expressions (see this for more info) to match the text that is between gifs: and , at the end of the same line in the HTML response. This is where we have a JSON list of 25 GIFs from the 1st results page.
  • jq ".[$(echo $(( $RANDOM % 25 )) )] | .images.original.url": here we use jq ".[] | .images.original.url" to parse the JSON list and get at the URL we need. The $(echo $(( $RANDOM % 25 )) ) is a Bash way of picking a random number between 0 and 25. Another way we could do this is shuf -i 0-25 -n 1 (see shuf manual pages for more info).
  • tr -d '"': finally, we trim the double-quotes from the URL.

That's it. Now, we can compose this utility with other tools to spread smiles, like $ gh pr review --approve --comment -b "![yay]($(giphy yay))"

Conclusion

This is why I love the terminal. It gives me the freedom and flexibility to creatively solve a problem and re-use it in composable ways. Check out this blog post for additional reading on the merits of CLIs.

I am, by no means, a Bash or Regular Expressions expert and I am sure there are many opportunities for improvement here. So, feel free to leave your ideas, thoughts, suggestions for improvements, or GIFs in the comments section below!

Also, contributions are welcome on the GitHub repo: https://github.com/pbnj/giphy-cli

Happy coding!

wave


Footnotes

* My Bash one-liner is not 100% dependency-free. It requires curl, rg for a consistent grep utility between macOS & Linux, & jq for command-line JSON parsing. Most GIF CLI utilities I found required system dependencies and entire development toolchains (e.g. ffmpeg, python3, dotnet, ...etc).

Top comments (0)