DEV Community

loading...

How Unix programmers at restaurants search menus for their favorite plate

Miguel Mota on December 13, 2018

A Unix programmer heads over to the local diner to get something to eat for lunch. He, or Bob as he prefers, knows better than to manually scan the...
Collapse
tomislacker profile image
Ben Tomasik

What sort of monster does cat | grep !?

Collapse
acidnik profile image
acidnik

With real life menus with millions of lines, you usually start with head | grep, and then, when you one-liner of 15 lines is complete, you replace head with cat and cross your fingers

Collapse
jeshan profile image
Jeshan Giovanni BABOOA

real life menus with millions each? ;)

Thread Thread
acidnik profile image
acidnik

That was my attempt to make a joke

Collapse
blackknight36 profile image
Michael • Edited

You can almost accomplish this entire task using awk. For example:

awk -F '$' '/shrimp/ {printf "%s- %.2f\n", $1, $NF}' < menu.txt

Collapse
chiefnoah profile image
Noah Pederson

But then you have to use awk 🤮

Collapse
rubberduck profile image
Christopher McClellan

awk is Turing Complete.
s/almost//

Collapse
jgomo3 profile image
Jesús Gómez

Some people, including me:

reddit.com/r/programming/comments/...

Collapse
pwntweets profile image
Pulkit Singhania

Grep won't be able to find anything because you are searching for ! Which is not in the menu

Collapse
moopet profile image
Ben Sinclair • Edited

I've been reading the thread about this on /r/programming (how circular!) and they're mostly (deliberately?) missing the point and trying to optimise it rather than to see it as a demonstration of pipes.

cough

grep -q 'shrimp.*$[0-9]\.' menu.txt && echo "Available" || echo ":("

EDIT: changed \d shortcode for [0-9] so it'll work with BSD and GNU grep.

Collapse
Sloan, the sloth mascot
Comment deleted
Collapse
kenbellows profile image
Ken Bellows • Edited

That's what this bit at the end is for:

$[0-9]\.

That bit of the regex will only match on a line that contains a dollar sign ($), a single digit ([0-9]), and a literal dot (\.). So "$2.99" will match, but "$12.99" won't, because there are two digits between the dollar sign and the dot.

Collapse
moopet profile image
Ben Sinclair

Try it.

Collapse
moopet profile image
Ben Sinclair

| rev | cut -d\ -f1 | rev

troll face

Collapse
catchenal profile image
Cat Chenal • Edited

Given this menu:

ps1$cat menu.txt

the menu

steak burrito $11.95
pasta and shrimp $9.75
caesar salad $6.50
shrimp salad $9.99
alfredo shrimp $10

My Nix programmer does this:

awk -F$ '/shrimp/{if ($NF < 10){ print $1}}' menu.txt

pasta and shrimp
shrimp salad

awk rules!

Collapse
labibllaca profile image
labibllaca

if you are looking for meals under 10 bucks, as shown in ($NF < 10), why isn't caesar salad($6.50) in the output ?

Collapse
jgomo3 profile image
Jesús Gómez

"test returns an exit status code of 1 if the condition passes or 0 if no match." It is actually backwards: reddit.com/r/programming/comments/...

Collapse
peterbertok profile image
Peter Bertok • Edited

The equivalent is much more readable with PowerShell:

$shrimp = Get-Content menu.txt | Select-String 'shrimp'
$price = $shrimp | ForEach-Object { $cols = $_ -split ' '; $cols[-1] }
$under10 = [decimal]$price.Substring(1) -lt 10
if ( $under10 ) { 'Available!' } else { ':(' }

Of course, you can use aliases to make this a bit "shorter", but then we're back in the world of Unix, where precious bytes have to be saved to achieve acceptable performance on 300 baud Teletype terminals:

$p = gc menu.txt | sls 'shrimp' | % { $c = $_ -split ' '; $c[-1] }
if ([decimal]$p.Substring(1) -lt 10) {'Available!'} else {':('}

Collapse
hoffmann profile image
Peter Hoffmann

Why are you guys alwas using awk for field separation? There ist cut -d" " -f3 that is nice as well

Collapse
agusnavce profile image
Agustin Navcevich

This is why two unix programmers will never eat together, because they will start to discuss which is the best way to order the shrimps

Collapse
sh0kry profile image
Mohamed Shoukry

Bob should've rounded up. He probably ran off when he remembered he didn't factor taxes in!
Oh & btw, he should've done a case insensitive grep grep -i shrimp menu.txt. Although if he's using awk anyway, then he might have included that there too and avoid all those unnecessary pipes! awk '$0~/shrimp/{print $NF}

Collapse
ppetermann profile image
ppetermann

In a lot of countries the tax is part of the price

Collapse
awwsmm profile image
Andrew (he/him)
Collapse
blackknight36 profile image
Michael

You need to replace your double quotes with literal single quotes. Here's why.

$ echo "Available!"
bash: !": event not found

$ echo 'Available!'
Available!

Collapse
swarupkm profile image
Swarup Kumar Mahapatra

This article is awesome. It really shows all the possibilities in Linux. I am quite surprised by the comments here where people are trying to correct you. Anyways, good job

Collapse
chbarts profile image
Chris Barts
Collapse
jeffprestes profile image
Jeff Prestes

hahaha, it's amazing! Congratulations.

Collapse
gmanon profile image
GManon

Hilarious!

Collapse
rdcloud85 profile image
Rick Cloud

Or, he could merely 'read' visually the menu??? Didn't realize this was a lesson in Unix coding until the end... :-) Laugh at me...

Collapse
slamotte profile image
Steve

I don't like how there's no code for how to scrape the website into menu. txt. Incomplete solution! ;-)

Collapse
lc_fd profile image
Luca Fedrizzi

Awesome!

Collapse
pawail profile image
Pawail A. Qaisar

Why.

Collapse
tameware profile image
tameware

It took me a while to realize that the price is truncated to an integer only because 'test' can't handle decimals. That might deserve a mention.

Collapse
blackknight36 profile image
Michael

Useless use of cat detected.

porkmail.org/era/unix/award.html