Stupid bash trick of the day

function _globdo
{
    local arg="$1"
    local dir=$(dirname $arg)
    local base=$(basename $arg)
    shift
    find $dir -name $base -exec "$@" {} \;
    set +f
}

alias globdo='set -f; _globdo'

The function/alias combo is get around automatic globbing and make it possible to specify glob patterns without having to quote them. See Simon Tathams’s Magic Aliases article for more info.

Examples of usage:

globdo *.c grep -H union
globdo /some/tree sed -i .bak 's/foo/bar/g'

Some tools like GNU grep already have recursive capabilities, but what I like about this approach is that it basically gives you recursive capabilities for all your tools and it does it in a consistent manner. To me it’s nicely in line with the Unix philosophy of having small tools that do particular tasks well and then stringing them together to create more complex behavior.

I hope that you find it useful. Comment if you have any improvements…

3 thoughts on “Stupid bash trick of the day

  1. I try to avoid using -exec these days. You get much better performance if you pipe find’s output in to xargs. While not as flexible as -exec, this also has the nice side effect of avoiding the globbing issue while simultaneously giving you significant performance improvements.

  2. Hi,

    if i have read correctly ths recursive glob function is just what im looking for! Unfortunatly im a bit of a novice when it comes to linux (started making my first bash scripts today), and i cant seem to get this thing working, or understand it works for that matter.

    Basically what i have is a script that is supposed to mount my cddrive, search for .jpg images, and transfer them to the computer. The problem im having is that i cant get the “*” wildcard to span multiple directories, becuase it doesnt have a recursive function. Here is the script:

    —————————script start——————
    #!/bin/bash
    #import (imp) bash script
    #mount cdrom

    shopt -s nocaseglob # enable nocaseglob
    mount /mnt/cdrom && ( echo cd has been mounted) || exit 0;

    # make a directory named with today.s date
    mkdir -v /video/pictures/$(date +%d-%m-%Y_”%H”:%M)_CD
    STR=$(date +%d-%m-%Y_”%H”:%M)_CD

    # change into this new directory

    cd /video/pictures/$STR

    # copy the entire contents of so named digital-photo-card to this directory

    cp -v /mnt/cdrom/r*.jpg /video/pictures/$STR && ( echo images have been found) ||(echo no images have been found ; umount /dev/cdrom)

    #if [ V = 1 ] ; then
    #exit 0
    #fi

    # announce task completed
    #echo .finished copying, renaming now..

    # announce task completed

    echo done copying, rotating now..

    # rotate all of the photos right-side-up according to embedded camera Exif data

    jhead -autorot *.jpg

    echo process finished, unmounting cd

    #unmount cd

    umount /dev/cdrom

    #done

    echo task completed successfully!

    #terminate

    exit 0

    ———————————-script end————–

    This is the line where i need the recursive function:

    cp -v /mnt/cdrom/r*.jpg /video/pictures/$STR && ( echo images have been found) ||(echo no images have been found ; umount /dev/cdrom)

    Do you have any suggestions on how i could implement your function into my script. Im sure there is a simple solution, but i simply cant get my head around it at the moment.

    Thanks,

    Damien

  3. Ok, sorry about that. I didnt reilize there was no formatting on this page. Thats going to be hard to read. Ill email it to you if you like.

Leave a Reply

Your email address will not be published. Required fields are marked *