Skip to content

Instantly share code, notes, and snippets.

@xaviershay
Created December 19, 2011 00:27
Show Gist options
  • Save xaviershay/1494931 to your computer and use it in GitHub Desktop.
Save xaviershay/1494931 to your computer and use it in GitHub Desktop.
bash golf problem
#!/bin/bash
# Input:
# output this 6
# do not output this 5
# output this 7
#
# Output (and a non-zero exit code):
# output this 6
# output this 7
THRESHOLD=5
cat test_file |
ruby -ne "puts \$_ if \$_.split(' ').last.to_i > \"${THRESHOLD}\".to_i" | \
ruby -e 'out = STDIN.read; puts out; exit(1) if out.length > 0'
@rhunter
Copy link

rhunter commented Dec 19, 2011

If even awk is too much of an external language, rev |cut|rev can get the last column.

$ cat test 
output this 6
do not output this 5
$ (xargs -L1 -I% bash -c '[ $(echo % | rev | cut -d\  -f 1 | rev) -gt $THRESHOLD ] && echo %' | grep . && exit 1 || exit 0 ) < test
output this 6
$ echo $?
1

Or if the character count is more important than readability:

(xargs -L1 -I% bash -c '[ $(echo %|rev|cut -d\  -f1|rev) -gt $THRESHOLD ]&&echo %'|grep .;exit $(($? != 0)))

@floere
Copy link

floere commented Dec 19, 2011

How about:

cat test_file | grep -qv ' [1-5]$'
exit $(($?^1))

This assumes that the threshold can be expressed as a nice regexp.

@xaviershay
Copy link
Author

nice ideas everyone. Inspired by floere, I found a nice way to replace the second ruby incantation in my script:

egrep ".+"

Will probably use awk to replace the first one.

@zaius
Copy link

zaius commented Dec 19, 2011

Not the shortest ever, but all bash:

while read line
do
 val=`echo $line | grep -Eo '[0-9]+'`
 if [[ "$val" -gt "$THRESHOLD" ]]; then
   echo $line
   exit 1
 fi
done

@xaviershay
Copy link
Author

added extra test data to negate early exit solutions.

@xaviershay
Copy link
Author

Combined above solutions to this:

#!/bin/bash

THRESHOLD=5

! cat test_file | \
  awk "\$NF > $THRESHOLD { print }" | \ # $NF = last field
  egrep ".+"                            # Set exit code if no output,
                                        # negated by preliminary `!`

@telemachus
Copy link

You can remove the cat and apply the awk line directly to the test_file - if we're still golfing.

awk "\$NF > $THRESHOLD { print }"  test_file

@floere
Copy link

floere commented Dec 19, 2011

Beautiful! :D

(Whoops! Accidental +1, sorry!)

@i5513
Copy link

i5513 commented Apr 29, 2016

@telemachus , you dont need print statement, it is the default behaviour

awk -v t=$THRESHOLD '$NF > t' test_file

Untested , but i'm sure it work , and less readable but shorter:

awk '$NF>'$THRESHOLD test_file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment