You are not logged in.

#476 2009-08-16 08:31:27

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: Post your handy self made command line utilities

#!/bin/bash
###Qname: Quick basic batch renaming.

#Defaults
TGT=""
FIX=""
INC=""
DIR="$PWD"
SHOW="yes"
MODE="" #single, global

function help_me () {
cat << END

==========================================================================
    USAGE: $(basename "$0") -g -t "STRING" -f "FIX"
           $(basename "$0") -s -f "FIX" -i "FILTER"

    --directory|-d) Specify target directory.               [PWD]
    --target|-t)    Specify a string to be replaced/removed.
            Don't use this option when you're doing prefixing!
            Use -i for the filtering instead.        [NONE]
    --fix|-f)       Specify a string to replace the target string, or
            to put as prefix to the filenames.          [NONE]
    --include|-i)   Use filter. Useful when prefixing.
                Also useful if you don't want to rename all files
            which contains STRING.                       [ALL]
    --single|-s)    Single replace MODE: only replace/remove the first
            occurance of target STRING.
    --global|-g)    Global replace MODE: replace/remove all instances 
                   of target STRING.
    --force|-F)     Do not ask for confirming.
    --help|-h)      print this help.

    NOTE: -s -g options are incompatible. If you specify more than
          one of these, only the last one is respected.
          -s -f without -t, it does prefixing!
==========================================================================

END
}

function display_rename () {
TGT="$1" ; FIX="$2" ; INC="$3" ; MODE="$4"
#Note we need to escape "Regular Expression Operators" for awk, with every character enclosed by [ ].
case "$MODE" in
        single)
        ls -1 | grep -F "$TGT" | grep -F "$INC" |
        awk -v tgt="$(echo "$TGT" | sed 's/./[&]/g')" -v fix="$FIX" '{ printf("mv -- \"%s\" ",$0);sub(tgt,fix);printf("\"%s\"\n",$0) }'
        ;;
        global)
        ls -1 | grep -F "$TGT" | grep -F "$INC" |
        awk -v tgt="$(echo "$TGT" | sed 's/./[&]/g')" -v fix="$FIX" '{ printf("mv -- \"%s\" ",$0);gsub(tgt,fix);printf("\"%s\"\n",$0) }'
        ;;
esac
}

function do_rename ()
{
cd "$DIR" 2>/dev/null && echo -e "\x1b[0;32m""$PWD""\x1b[00;00m"

if [ "$?" != "0" ] ; then
echo '** Directory "'"$DIR"'" does not exist! **' ; echo ; exit 1
fi

if [ "$SHOW" == "yes" ] ; then
    echo '* Careful *'
    echo '-------------------------------------------------------------------------'
    display_rename "$1" "$2" "$3" "$4"
    echo '-------------------------------------------------------------------------'
    echo -n '* Rename Files? [y/n].. '
    read ANS
    case "$ANS" in
        y|Y) display_rename "$1" "$2" "$3" "$4" | sh
             echo '* Files renamed.'
        ;;
        n|N) echo '* Nothing renamed.'
        ;;
        *)   echo '* Wrong answer!' ; exit 1
        ;;
    esac
elif [ "$SHOW" == "no" ] ; then
    display_rename "$1" "$2" "$3" "$4" | sh ; echo '* Files renamed!'
fi
}

#Options
OPT_TEMP=$(getopt --longoptions directory:,target:,include:,fix:,single,global,force,help --options d:t:f:i:sgFh -- "$@")

eval set -- "$OPT_TEMP"

while : ; do
case "$1" in
    --directory|-d) DIR="$2"   ; shift 2  ;;
    --target|-t)    TGT="$2"   ; shift 2  ;;
    --fix|-f)       FIX="$2"   ; shift 2  ;;
    --include|-i)   INC="$2"   ; shift 2  ;;
    --single|-s)    MODE="single" ; shift ;;
    --global|-g)    MODE="global" ; shift ;;
    --force|-F)     SHOW="no"  ; shift    ;;
    --help|-h)      help_me    ; exit 0   ;;
    --)             shift      ; break    ;;
    *)              echo 'Wrong option!' ; exit 1 ;;
esac
done

#Do it
echo
case "$MODE" in
    single)
    do_rename "$TGT" "$FIX" "$INC" single 
    ;;
    global)
    do_rename "$TGT" "$FIX" "$INC" global
    ;;
    *)
    echo '** You must specify MODE, see -h for more info. **'
    ;;
esac
echo

What it does is very basic. It replaces a specific STRING in filenames from DIR with FIX: replace the first instance only or replace all. It also does prefixing. With interactive mode and force mode. The --help describes it rather clearly.

Example Output:

Qname -s -t '[ANBU-Frostii]' -f '[BSS]' -d ..

/media/A/Tokyo Magnitude 8.0
* Careful *
-------------------------------------------------------------------------
mv -- "[ANBU-Frostii]_Tokyo_Magnitude_8_-_01_-_[720p][E5C69941].mkv" "[BSS]_Tokyo_Magnitude_8_-_01_-_[720p][E5C69941].mkv"
mv -- "[ANBU-Frostii]_Tokyo_Magnitude_8_-_02_-_[720p][C527D655].mkv" "[BSS]_Tokyo_Magnitude_8_-_02_-_[720p][C527D655].mkv"
mv -- "[ANBU-Frostii]_Tokyo_Magnitude_8_-_03_-_[720p][74F4FEC9].mkv" "[BSS]_Tokyo_Magnitude_8_-_03_-_[720p][74F4FEC9].mkv"
mv -- "[ANBU-Frostii]_Tokyo_Magnitude_8_-_04_-_[720p][0DCD1E0D].mkv" "[BSS]_Tokyo_Magnitude_8_-_04_-_[720p][0DCD1E0D].mkv"
-------------------------------------------------------------------------
* Rename Files? [y/n].. n
* Nothing renamed.

I believe there is something like this already out there, probably much more sophisticated. Please let me know.
BTW, the rename command on my machine seems to be a really basic version... I remember there is another better rename command out there? Please also let know.  --> Oh, found it! It's prename from debian based distros. prename is in AUR, and the GTK2 gprename is in community! Alternatively, you can get the prename script here.

Also, if somebody's gonna improve my code above, you're welcome! I'll be very interested wink Thanks.

Last edited by lolilolicon (2009-08-17 15:35:37)


This silver ladybug at line 28...

Offline

#477 2009-08-17 22:48:24

spupy
Member
Registered: 2009-08-12
Posts: 218

Re: Post your handy self made command line utilities

MPyC - A simple pygtk util for changing the playing MPD song. Requires mpc, pygtk.
When started, shows a windows with only a text field. You start typing the name of an artist, album or song. The filtered songs from your currently playing mpd playlist will appear. There is autocompletion - I'm not sure if it even works (I didn't get it quite right), but if you press enter while typing, the first song in the filtered list will start playing. Ctrl+Q to quit.
It was from my early days with python, so I don't remember how the gtk.EntryCompletion works or what other hacks there are.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pygtk
import gtk
import commands as cmd
import sys

class MPDCompletion:
    def __init__(self):
        window = gtk.Window()
        window.set_title("MPyC")
        window.connect('destroy', lambda w: gtk.main_quit())
        #--- Accelerators
        accel_group = gtk.AccelGroup()
        window.add_accel_group(accel_group)
        accel_group.connect_group(ord('q'), gtk.gdk.CONTROL_MASK, gtk.ACCEL_LOCKED, lambda w,x,y,z: gtk.main_quit())
        #---
        vbox = gtk.VBox()
        label = gtk.Label('Type song name to search')
        vbox.pack_start(label)
        entry = gtk.Entry()
        vbox.pack_start(entry)
        window.add(vbox)

        completion = gtk.EntryCompletion()
        self.liststore = gtk.ListStore(str)
        self.liststore.set_column_types(str, str, str, str, str)

        playlist = self.mpd_get_playlist()
        for song in playlist:
            self.liststore.append(song)
        completion.set_model(self.liststore)
        completion.set_inline_selection(True)
        entry.set_completion(completion)
        completion.set_text_column(4) # show the full song string
        completion.set_match_func(self.compare_func, None)
        completion.connect('match-selected', self.match_cb)
        entry.connect('activate', self.activate_cb)

        window.resize(500,50)
        window.show_all()
        return

    def compare_func(self, completion, entrystr, iter, data=None):
        """
            This function checks if a row from the liststore should be filtered. It searchs for arist name, title and album
        """
        entrystr = entrystr.lower()
        model = completion.get_model()
        artist = model[iter][1]
        title = model[iter][2]
        album = model[iter][3]
        #~ print modelstr, "+", entrystr, ":", modelstr.lower().startswith(entrystr)
        artist_match = artist.lower().startswith(entrystr)
        title_match = title.lower().startswith(entrystr)
        album_match = album.lower().startswith(entrystr)
        if artist and title and album:
            return (artist_match or title_match or album_match)


    def match_cb(self, completion, model, iter):
        """
            This callback is invoked when a matching entry has been selected
        """
        song_num = model[iter][0]
        full = model[iter][4]
        #~ print "Playing:", song_num, full
        self.mpd_play_song(song_num)
        gtk.main_quit()
        return

    def activate_cb(self, entry):
        """
            This is activated when Enter is pressed in the entry without a selected match.
            We get a list of songs mathing only the title, and play the first one
        """
        text = entry.get_text().lower()
        for row in self.liststore:
            if row[1].lower().startswith(text) or row[2].lower().startswith(text):
                self.mpd_play_song(row[0])
                gtk.main_quit()
                return
        return

    def mpd_parse_line(self, line):
        """
            Break a line into a (song number, artist, title, album) tuplea
        """
        line = line.strip()
        num, data = line.split(' ', 1)
        num = num.strip('()> ')
        tags = data.split('%')
        artist = self.mpd_filter_special_symbols(tags[0])
        title = self.mpd_filter_special_symbols(tags[1])
        album = self.mpd_filter_special_symbols(tags[2])
        full = artist + " - " + title + " (" + album + ")"
        return num, artist, title, album, full

    def mpd_filter_special_symbols(self, string):
        """
            Filter-out some special symbols I can't display. There are more, but I haven't found the codes yet.
            TODO: Un-ugly-fy this function. Is this even needed? I don't remember.
        """
        if string=="":
            return "Unknown"

        symbols = {}
        symbols["\xc3\x82"] = "A" # Â
        symbols["\xc3\xa4"] = "a" # ä
        symbols["\xc3\xb6"] = "o" # ö
        symbols["\xc3\xbc"] = "u" # ü
        symbols["\xc3\x9c"] = "U" # Ü
        for sym in symbols.iterkeys():
            if sym in string:
                string = string.replace(sym, symbols[sym])
        return string

    def mpd_get_playlist(self):
        """
            Returns a list of tuples, each tuples represent one song
        """
        playlist_cmd = 'mpc playlist --format [%artist%]%[%title%]%[%album%]'
        status, playlist_raw = cmd.getstatusoutput(playlist_cmd)
        if status == 256:
            sys.exit("MPD not running")
        playlist_lines = playlist_raw.split('\n')
        playlist = []

        for line in playlist_lines:
                playlist.append(self.mpd_parse_line(line))

        return playlist

    def mpd_play_song(self, num):
        """
            Plays the song at the given position.
        """
        cmd.getoutput("mpc play "+str(num))

if __name__ == "__main__":
    mc = MPDCompletion()
    gtk.main()

Last edited by spupy (2009-08-17 22:49:06)


There are two types of people in this world - those who can count to 10 by using their fingers, and those who can count to 1023.

Offline

#478 2009-08-18 02:35:27

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

Re: Post your handy self made command line utilities

markp1989 wrote:

I have a script that does the same with googles define feature

dictionary(){ 
echo Definitions of  $1 on the Web:
echo " "
curl -s -A 'Mozilla/4.0'  'http://www.google.co.uk/search?q=define%3A+'$1  | html2text -ascii -nobs -style compact -width 500 | grep "*" | head -n 5
}

Oooohhh!  Very nice.  Been working on this for awhile trying with wordnet but this is a pretty good way to go about it.  Hope you don't mind but I decided to add on to it.  Added newlines between definitions, highlighting, and indentation:

#!/bin/bash
# define - command line dictionary

if [[ -z $1 ]]; then
  echo " define <word-to-lookup> - command line dictionary"; else
  curl -s -A 'Mozilla/4.0'  'http://www.google.co.uk/search?q=define%3A+'$1 \
  | html2text -ascii -nobs -style compact -width 500 | grep "*" | head -n 5 \
  | fold -s --width=79 | sed -e 's/    \*/ \*/g' | sed -e 's/*/\n&/g' | \
  sed -e 's/^/ /' | sed -e '$G' | grep -i --color -A 111111 -B 99999999 -e \
  $1 -e "\*"
fi

Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

#479 2009-08-19 08:56:47

markp1989
Member
Registered: 2008-10-05
Posts: 431

Re: Post your handy self made command line utilities

Gen2ly wrote:
markp1989 wrote:

I have a script that does the same with googles define feature

dictionary(){ 
echo Definitions of  $1 on the Web:
echo " "
curl -s -A 'Mozilla/4.0'  'http://www.google.co.uk/search?q=define%3A+'$1  | html2text -ascii -nobs -style compact -width 500 | grep "*" | head -n 5
}

Oooohhh!  Very nice.  Been working on this for awhile trying with wordnet but this is a pretty good way to go about it.  Hope you don't mind but I decided to add on to it.  Added newlines between definitions, highlighting, and indentation:

#!/bin/bash
# define - command line dictionary

if [[ -z $1 ]]; then
  echo " define <word-to-lookup> - command line dictionary"; else
  curl -s -A 'Mozilla/4.0'  'http://www.google.co.uk/search?q=define%3A+'$1 \
  | html2text -ascii -nobs -style compact -width 500 | grep "*" | head -n 5 \
  | fold -s --width=79 | sed -e 's/    \*/ \*/g' | sed -e 's/*/\n&/g' | \
  sed -e 's/^/ /' | sed -e '$G' | grep -i --color -A 111111 -B 99999999 -e \
  $1 -e "\*"
fi

Looks neat, i like the indentation one thing i noticed is that if i do define "arch linux"

i get the error : grep: linux: No such file or directory

with the 1 i did, it would work if you quoted 2 words.


Desktop: E8400@4ghz - DFI Lanparty JR P45-T2RS - 4gb ddr2 800 - 30gb OCZ Vertex - Geforce 8800 GTS - 2*19" LCD
Server/Media Zotac GeForce 9300-ITX I-E - E5200 - 4gb Ram - 2* ecogreen F2 1.5tb - 1* wd green 500gb - PicoPSU 150xt - rtorrent - xbmc - ipazzport remote - 42" LCD

Offline

#480 2009-08-19 17:45:54

fflarex
Member
Registered: 2007-09-15
Posts: 466

Re: Post your handy self made command line utilities

@markp1989 and Gen2ly: Here's my version of the script. It has a reduced pipeline (less programs piping output to each other - the main reason I did this), similar formatting to Gen2ly's script, and a code cleanup of various mistakes and pet peeves of mine. I have implemented the fold command in sed some time in the past as well, so I'm convinced I could reduce everything after html2text into a single sed command, but it's not worth the effort. There are some things you may want to change: the google URL is now google.com, so you could change it back to google.co.uk, and the highlighting uses bold blue for the asteriks and bold green for the search term, so you could change the escape sequences I use to change the colors to your preference (google for "xterm color escape sequences").

#!/bin/sh
# command line dictionary

if [ -z "$1" ]; then
    printf ' %s <word-to-lookup> - command line dictionary\n' $(basename $0)
else
    curl -s -A 'Mozilla/4.0'  'http://www.google.com/search?q=define%3A+'"$1" \
    | html2text -ascii -nobs -style compact -width 500                        \
    | sed -n '/^Definitions/ {N;N;N;N;N;s/   //g;p;q}'                        \
    | fold -s --width=79                                                      \
    | sed -e '/^ / !s/.*/   &/'     -e '/\*/ s/.*/\n&/;$G'                    \
          -e 's/*/\c[[1;34m*\c[[m/' -e 's/'"$1"'/\c[[1;32m'"$1"'\c[[m/'
fi

Last edited by fflarex (2009-08-20 04:33:15)

Offline

#481 2009-08-19 18:08:18

Barrucadu
Member
From: York, England
Registered: 2008-03-30
Posts: 1,158
Website

Re: Post your handy self made command line utilities

So… I'm the only one who used a DICT server for that? tongue

Offline

#482 2009-08-19 20:24:23

fflarex
Member
Registered: 2007-09-15
Posts: 466

Re: Post your handy self made command line utilities

@Barrucadu: I know there is a better way to do it, but I just couldn't stand to see a script with so many unnecessary pipes. I rarely need to look up words anyways.

Offline

#483 2009-08-19 20:33:36

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Post your handy self made command line utilities

/me thinks you have unnecessary pipes! big_smile

┌─[ 16:31 ][ blue:~ ]
└─> grepp define .bash_functions
# go to google for a definition
define() {
  local LNG=$(echo $LANG | cut -d '_' -f 1)
  local CHARSET=$(echo $LANG | cut -d '.' -f 2)
  lynx -accept_all_cookies -dump -hiddenlinks=ignore -nonumbers -assume_charset="$CHARSET" -display_charset="$CHARSET" "http://www.google.com/search?hl=${LNG}&q=define%3A+${1}&btnG=Google+Search" | grep -m 5 -C 2 -A 5 -w "*" > /tmp/define
  if [ ! -s /tmp/define ]; then
    echo "No definition found."
    echo
  else
    echo -e "$(grep -v Search /tmp/define | sed "s/$1/\\\e[1;32m&\\\e[0m/g")"
    echo
  fi
  rm -f /tmp/define
}

Offline

#484 2009-08-19 21:53:44

fflarex
Member
Registered: 2007-09-15
Posts: 466

Re: Post your handy self made command line utilities

I really don't think your solution looks any better than mine. For one thing, you haven't cut down on pipes at all; we both use 4 of them. You've also added a temporary file and invoked echo twice as much as necessary (plus I just hate the echo command in general).

In any case, Barrucadu's solution is both simpler and more elegant than any of ours. It could maybe use a bit of formatting for the output, though.

Last edited by fflarex (2009-08-19 22:01:35)

Offline

#485 2009-08-19 22:03:49

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

Re: Post your handy self made command line utilities

markp1989 wrote:

Looks neat, i like the indentation one thing i noticed is that if i do define "arch linux"

i get the error : grep: linux: No such file or directory

with the 1 i did, it would work if you quoted 2 words.

Yeah, this could probably be fixed by using "$@" but I haven't tried it.

fflarex wrote:

... and the highlighting uses bold blue for the asteriks and bold green for the search term, so you could change the escape sequences I use to change the colors to your preference (google for "xterm color escape sequences").

#!/bin/sh
# command line dictionary

if [ -z "$1" ]; then
    printf " %s <word-to-lookup> - command line dictionary\n" $(basename $0)
else
    printf "Definitions of \x1b[1;32m%s\x1b[m on the Web:\n" "$1"
    curl -s -A 'Mozilla/4.0'  'http://www.google.com/search?q=define%3A+'"$1" \
    | html2text -ascii -nobs -style compact -width 500                        \
    | sed -n '/^Definitions/ {n;N;N;N;N;s/   //g;p;q}'                        \
    | fold -s --width=79                                                      \
    | sed -e '/^ / !s/.*/   &/'     -e '/\*/ s/.*/\n&/;$G'                    \
          -e 's/*/\c[[1;34m*\c[[m/' -e 's/'"$1"'/\c[[1;32m'"$1"'\c[[m/'
fi

Got more to learn with sed looks like, does chomp it down nicely.  Didn't know that -e could be defined multiple times, and still have no idea what '/^ / !s/.*/  &/' does.  Looks like: beginning of line, do not replace, everything,  &(???).  I also like the idea of useing escape sequences inside sed.  Didn't know that was possible.

Barrucadu wrote:

So… I'm the only one who used a DICT server for that? tongue

Last time I used the dict server the definitions were pretty aged (at least the wordnet ones) and incomplete.  I don't think it's been updated for quite a bit.

Brisbin, good to think charset and lang, definitely makes the script more portable.

This inspired me to fix my wordnet script.  Wordnet is the Princeton database of words.  Can be pretty slow at times, but good for more technical definition of words (more like you see in common dictionaries).  Added spell-suggestion (needs aspell and local language dictionary installed), and used fflarex suggestion for coloring:

#!/bin/bash
# define - command line dictionary

DICTCHECK=$(echo "$1" | aspell -a | sed '1d' | wc -m)

# Usage if parameter isn't given
if [[ -z $1 ]]; then
  echo " define <word-to-lookup> - command line dictionary"
  exit 1
fi

# Suggestions if word is not in dictionary, otherwise define
if [[ $DICTCHECK -gt "3" ]]; then
  echo "$@" | aspell -a | sed '/Ispell/ c\\nNot in dictionary, possible alternatives:\n'| sed 's/^.*: //'
  exit 2; else
  links -dump http://wordnetweb.princeton.edu/perl/webwn?s="$1" | sed \
  '1,5d' | sed '$d' | sed '$G' | sed 's/^ //' | sed 's/^    /  /' | sed \
  's/S\: //' | sed -e 's/*/\c[[1;37m*\c[[m/' -e 's/'"$1"'/\c[[4;37m'"$1"'\c[[m/'
fi

Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

#486 2009-08-19 22:54:39

fflarex
Member
Registered: 2007-09-15
Posts: 466

Re: Post your handy self made command line utilities

'/^ / !s/.*/   &/' will add 3 spaces to the beginning of any line which does not already begin with a space.

The first part is a pattern which means to only apply this command to lines which contain the pattern (similar to the line numbers you just used in the above script). The exclamation negates that, so that it applies to all lines which do not match the pattern. The ampersand is shorthand for "the pattern matched earlier in the command". So it replaces the 'line' with '3 spaces + line'.

It's not as complicated as it looks. You could learn all of sed's syntax in one weekend if you wanted. Perl is probably a better tool for manipulating text, but it would take a lot longer to learn so I've never bothered (although if I ever did, I've heard that sed knowledge transfers nicely to perl).

Last edited by fflarex (2009-08-19 23:04:35)

Offline

#487 2009-08-20 00:47:35

Daenyth
Forum Fellow
From: Boston, MA
Registered: 2008-02-24
Posts: 1,244

Re: Post your handy self made command line utilities

Update all out of date dependencies of a given package

pacman -S $(comm -1 -2 <(pacman -Qqu) <(pactree -u PKGNAME  | sort))

Last edited by Daenyth (2009-08-20 00:48:01)

Offline

#488 2009-08-20 01:05:06

colbert
Member
Registered: 2007-12-16
Posts: 809

Re: Post your handy self made command line utilities

How can I get the bash prompt to show month.day before the time? Time is \A after the first YELLOW:

PS1="\[$BLUE\]┌─\[$PURPLE\][ \[$YELLOW\]\A \[$PURPLE\]][ \[$LIGHTGREEN\]\w \[$PURPLE\]]\n\[$BLUE\]└─\[$YELLOW\]> \[$LIGHTGRAY\]"

Offline

#489 2009-08-20 01:10:28

Daenyth
Forum Fellow
From: Boston, MA
Registered: 2008-02-24
Posts: 1,244

Re: Post your handy self made command line utilities

Use $(date --format foo) ?

Offline

#490 2009-08-20 01:13:06

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Post your handy self made command line utilities

you can probably put a $(date +whatever) in there, right?

/edit: too slow...

Last edited by brisbin33 (2009-08-20 01:15:37)

Offline

#491 2009-08-20 01:21:18

colbert
Member
Registered: 2007-12-16
Posts: 809

Re: Post your handy self made command line utilities

Ahh, beautiful, didn't think about that for .bashrc, just added $(date +%c), thanks fellas smile

Offline

#492 2009-08-20 01:25:46

Daenyth
Forum Fellow
From: Boston, MA
Registered: 2008-02-24
Posts: 1,244

Re: Post your handy self made command line utilities

I like to add `pom` next to `date` in my .bashrc (pacman -S bsd-games)

Offline

#493 2009-08-20 01:38:54

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

Re: Post your handy self made command line utilities

lol, what?


Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

#494 2009-08-22 08:04:47

devyn
Member
Registered: 2009-01-01
Posts: 20

Re: Post your handy self made command line utilities

Hi everyone, I have made a twitter client in Ruby: http://gist.github.com/172702.
It's very colorful.
I hope everyone likes it, as I find it very useful. I work from the Terminal (rxvt-unicode, to be exact) for hours on end, and posting to twitter is a nice break. I want a way to do it quickly, so I made this.

Any criticism/comments are appreciated, as always.

Offline

#495 2009-08-23 01:41:45

fflarex
Member
Registered: 2007-09-15
Posts: 466

Re: Post your handy self made command line utilities

Here is a script which waits until the currently playing song in MPD has changed, then exits. It is useful for doing things like shutting off the computer after 4 more songs have finished, etc. It is the direct successor to mpd-on-change, but with a couple advantages: it doesn't constantly poll MPD, and it works correctly even if the same exact file is played twice in a row. I consider it pretty much complete, except for possible bug fixes (and also if I can figure out how to make it work without the named pipe voodoo). It requires some version of netcat (tested with nc, ncat, and gnu-netcat). I'm interested in hearing how it works for other people, especially those who connect to remote instances of MPD or use a password.

Example uses:

mpd-wait -n4; halt

env MPD_HOST=password@host MPD_PORT=port mpd-wait

while mpd-wait --songs=2; do
    custom-osd-script.sh
done
#!/bin/sh
# Script to wait for the currently playing song in MPD to change.
# Uses netcat to communicate directly with the MPD server.

# Name of the script
progname=$(basename "$0")

# Find and save a unique file name for the temporary FIFO
tmpfifo=/tmp/."$progname".$$
while [ -e "$tmpfifo" ]; do
    tmpfifo="$tmpfifo.$(tr -dc 0-9 < /dev/urandom | head -c2)"
done

# Remove temporary FIFO if the script is killed
trap "rm \"$tmpfifo\"; exit" SIGHUP SIGINT SIGTERM

# Print a help message
usage() {
    fmt --split-only --width=$(tput cols) <<- EOF
    Usage: $progname [options]
    Wait for the currently playing song in MPD to change, then exit.

    Options:
      -n, --songs
             Set the number of songs to wait for (defaults to 1).
      -h, --help
             Display this help message and exit.

    Environment Variables:
      MPD_HOST, MPD_PORT
        The host and port of the MPD server you wish to connect with. The default is to connect to localhost on port 6600.  To use a password with MPD, set MPD_HOST to password@host.

    Note that if no song is currently playing, then the script will wait for one to start instead. This script requires netcat or some compatible derivative thereof.
    EOF
}

# Default values for MPD's host and port
mpd_host=localhost
mpd_port=6600

# Check environment variables for alternate values
if [ "$MPD_HOST" ] && $(printf %s "$MPD_HOST" | grep @ &>/dev/null); then
    mpd_host="$(printf $MPD_HOST | sed 's/.*@//')"
    mpd_pass="$(printf $MPD_HOST | sed 's/\(.*\)@.*/\1/')"
elif [ "$MPD_HOST" ]; then
    mpd_host="$MPD_HOST"
fi
if [ "$MPD_PORT" ]; then
    mpd_port="$MPD_PORT"
fi

# Number of songs to wait for. Default is 1.
nsongs=1

# Detect command line arguments
argv=$(getopt -a -o n:h --long songs:,help -n "$progname" -- "$@")
test $? != 0 && exit 1
eval set -- "$argv"
while [ "$1" ]; do
    case "$1" in
        -n | --songs )    shift
                          nsongs="$1"
                          ;;
        -h | --help )     usage
                          exit
                          ;;
        -- )              shift
                          break
                          ;;
        * )               printf '%s: uh oh, major internal error!\n' "$progname" >&2
                          exit 1
    esac
    shift
done

# Determine netcat executable to use
for exe in nc ncat netcat; do
    nc="$(which $exe 2>/dev/null)" && break
done
test -z "$nc" && printf '%s: netcat is a dependency of this script\n' "$progname" >&2

# Tests that MPD is running
printf 'ping\nclose\n' | $nc $mpd_host $mpd_port | grep '^OK MPD [0-9.]*' &>/dev/null \
|| { printf '%s: daemon is not running\n' "$progname" >&2;  exit 2; }

# Tests that $nsongs is a non-negative integer
test $nsongs -ge -1 2>/dev/null                                               \
|| { printf '%s: argument to '\'--songs\'' or '\'-n\'' must %s\n' "$progname" \
            'be a non-negative integer' >&2
     exit 1; }

# Gets MPD's internal ID for the current song, which is unique even for
# identical files in the playlist
getsongid() {
    printf '%s\nstatus\nclose\n'                                         \
           "$(test \"$mpd_pass\" && printf 'password %s' \"$mpd_pass\")" \
    | $nc $mpd_host $mpd_port                                            \
    | sed -ne '/^state: stop$/ q'                                        \
           -e '/^songid: / s///p'
}

# ID for the song we're waiting for
songid=$(getsongid)

# Create temporary FIFO
mknod --mode=600 "$tmpfifo" p

# $count keeps track of how many songs have changed
# This is the meat of the script, which keeps track of the current song and
# whether or not it has changed. The very confusing voodoo with the named pipe
# is to prevent netcat from hanging after the "idle" command has finished.
# (Possible security risk - attacker could manipulate the daemon by piping to
#  the named pipe before the script does.)
count=0
until [ $count -eq $nsongs ]; do
    while [ "$songid" = "$(getsongid)" ]; do
        printf '%s\nidle player\n'                                           \
               "$(test \"$mpd_pass\" && printf 'password %s' \"$mpd_pass\")" \
        | cat - "$tmpfifo"                                                   \
        | $nc $mpd_host $mpd_port                                            \
        | sed -n "/^changed.*/ s//close/w $tmpfifo"
    done
    count=$(($count + 1))
    songid=$(getsongid)
done

# Remove temporary FIFO
rm "$tmpfifo"

EDIT: Please note that if you just copy/paste this, the help message will not display as intended. This is because the tabs were converted to spaces by the forum. Just change the leading four spaces in the usage() function to tabs to fix it.

Last edited by fflarex (2009-08-23 04:31:32)

Offline

#496 2009-08-24 01:21:58

marxav
Member
From: Gatineau, PQ, Canada
Registered: 2006-09-24
Posts: 386

Re: Post your handy self made command line utilities

Here is a perl version of the define function.  Still needs some clean up, but no pipes used smile.  Should make brisbin happy.;)

#!/usr/bin/perl
use strict;
use LWP::Simple qw/get $ua/;
my $content; #What is found at $url
my $url;     #url to get
my $word2define=join (' ',@ARGV); #
my $definitions;
my @definitions;
my $TXTYLW="\e[0;33m"; # Yellow
my $TXTGRN="\e[0;32m"; # Green
my $TXTRST="\e[0m";    # Text Reset
sub define{
    $ua->agent("Mozilla/4.0");
    $url="http://www.google.ca/search?q=define%3A+@ARGV";
    $content = get("$url");
    die "Cannot open $url " unless defined $content;
}

sub parse{
    @definitions = ($content =~ m#<li>(.*?<br>)#g);
    foreach (@definitions){
        s/<br>/\n\n/;
        s/^/$TXTGRN\*$TXTRST/;
        s/($word2define)/$TXTYLW\1$TXTRST/i;
        print ("$_");
    }
}

&define;
&parse;

Offline

#497 2009-08-25 20:12:00

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Post your handy self made command line utilities

so here's a really short one i use to convert < and > to < and > for use in an html document.  typically, i'll be editing a webpage in vim so i can just:

:r ! text2html < /some/script.sh

to pull a script right into the <pre> blocks of whatever page i'm currently writing.  you can also just run it on commandline; it's a simple STDIN -> STDOUT filter.

the script:

IFS="\n"

while read -r LINE; do 
  sed 's/</\&lt\;/g;s/>/\&gt\;/g' <<< "$LINE"
done

unset IFS

/edit: sorry, found my own useless use of cat... and removed a pipe!

Last edited by brisbin33 (2009-08-25 20:13:25)

Offline

#498 2009-08-25 21:58:47

Daenyth
Forum Fellow
From: Boston, MA
Registered: 2008-02-24
Posts: 1,244

Re: Post your handy self made command line utilities

You should s/\&/&/ before anything else also. Personally I'd rather use perl + a module to escape it.. there's too many cases that a sed would have to cover.

Offline

#499 2009-09-04 06:02:36

brenix
Member
From: California
Registered: 2008-03-05
Posts: 185

Re: Post your handy self made command line utilities

Not sure if anyone would be interested, but i've created a small script that I use right after I (re)install Arch. It's a post-install script that is somewhat based off what is done on the wiki (adding users, installing xorg, etc). Since I tend to install arch on numerous machines, this has came in very handy..

Note: It's a bit messy. The script installs random things at some times, just cause I was too lazy to move them somewhere else. Take a look for yourself.

#!/bin/bash
#
# Description: A small script I created to speed up the configuration process of Archlinux. This script assumes
#              you already have configured your network adapters and rc.conf for basic settings so pacman will work.
# Last Updated: 8.10.09
# Author: brenix

#Colors
blue="\E[1;34m"
green="\E[1;32m"
red="\E[1;31m"
bold="\E[1;37m"
default="\E[0m"

#-------Check for root-------#
if [ $(whoami) != "root" ]; then
    echo -en "$red Error:$default you cannot performan this operation unless you are root."
    exit 1
fi

#------Edit nameservers------#
read -p "Edit Nameservers[y/n]?  "
if [ "$REPLY" == "y" ]; then
    vi /etc/resolv.conf
    echo -en "$blue :: Completed :: $default\n"
fi

#---Verify the database is up to date before installing anything---#
pacman -Syy

#---Install yaourt/powerpill----#
read -p "Install yaourt/powerpill[y/n]? "
if [ "$REPLY" == "y" ]; then
    pacman --noconfirm -S abs aria2 subversion git python rxvt-unicode bash-completion #random stuff added here
    abs # Sync ABS Tree
    cd /tmp
    wget http://aur.archlinux.org/packages/yaourt/yaourt.tar.gz
    tar -zxvf yaourt.tar.gz
    cd yaourt
    makepkg -i --asroot
    vi /etc/yaourtrc
    pacman -S --noconfirm abs
    chmod -R 777 /var/abs # Dont ask... heh..
    echo -en "$blue You must add user  ALL=NOPASSWD: /usr/bin/pacman and /usr/bin/pacdiffviewer to the sudoers" # Reminder..
    sleep 10
    visudo
    yaourt -S --noconfirm powerpill
    cd ~
    echo -en "$blue :: Completed :: $default\n"
fi

#----Install pkgd--------------#
read -p "Install pkgd[y/n]? "
if [ "$REPLY" == "y" ]; then
    yaourt -S --noconfirm pkgd
    vi /etc/pkgd.conf       # Customization
    vi /etc/pacman.conf     
    vi /etc/rc.conf         # Add pkgd daemon to rc.conf
    echo -en "$blue :: Completed :: $default\n"
fi

#----Sort mirrors by their speed----#
read -p "Sort Mirrors by Speed[y/n]? "
if [ "$REPLY" == "y" ]; then
    pacman -S --noconfirm python
    cd /etc/pacman.d
    cp mirrorlist mirrorlist.backup
    rankmirrors -n 6 mirrorlist.backup > mirrorlist
    pacman -Syy
    cd ~
    echo -en "$blue :: Completed :: $default\n"
fi

#--------Update System-----------#
read -p "Update System[y/n]? "
if [ "$REPLY" == "y" ]; then
    pacman -Syu --noconfirm
   # echo -en "$bold Re-ranking mirrors... $default"
   # cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
   # rankmirrors -n 6 /etc/pacman.d/mirrorlist.backup > /etc/pacman.d/mirrorlist
    echo -en "$blue :: Completed :: $default\n"
fi

#---------Add user---------------#
read -p "Add a new user[y/n]? "
if [ "$REPLY" == "y" ]; then
    echo -en "$green Enter username: $default "
    read USERNAME
    useradd -m -G audio,optical,storage,video,wheel,power,network -s /bin/bash $USERNAME # Add new user with common groups
    passwd $USERNAME
    echo -en "$blue :: Completed :: $default\n"
fi

#---------Install Alsa----------#
read -p "Install Alsa[y/n]? "
if [ "$REPLY" == "y" ]; then
    pacman -S --noconfirm alsa-utils
    alsamixer
    read -p "Was your sound card detected[y/n]? "
    if [ "$REPLY" == "y" ]; then
        echo -en "$bold Testing sound... $default"
        aplay /usr/share/sounds/alsa/Front_Center.wav # Test audio
        vi /etc/rc.conf # Add alsa to daemons line..
        echo -en "$blue :: Completed :: $default\n"
    else
        alsaconf
        alsamixer
        vi /etc/rc.conf # Add alsa to daemons line..
        echo -en "$blue :: Completed :: $default\n"
    fi
fi

#--------Install Xorg----------#
read -p "Install Xorg[y/n]? "
if [ "$REPLY" == "y" ]; then
    pacman -S --noconfirm libgl xorg xf86-input-evdev xf86-input-keyboard xf86-input-mouse ttf-ms-fonts ttf-dejavu ttf-bitstream-vera gtk2
    echo -en "$green Enter video (i.e. nvidia or xf86-video-intel): $default"
    read VIDEO
    yaourt -S --noconfirm $VIDEO 
    Xorg -configure
    cp /root/xorg.conf.new /etc/X11/xorg.conf
    vi /etc/X11/xorg.conf
    cp /etc/skel/.xinitrc /home/$USERNAME/
    echo exec xterm >> /home/$USERNAME/.xinitrc
    chown $USERNAME:users /home/$USERNAME/.xinitrc
    chmod 755 /home/$USERNAME/.xinitrc
    echo -en "$blue :: Completed :: $default\n"
fi

#-------Istall VIM------------#
read -p "Install VIM[y/n]? "
if [ "$REPLY" == "y" ]; then
    powerpill -S --noconfirm vim
    echo -en "$blue :: Completed :: $default\n"
fi

#-------Install MPD/NCMPCPP----#
read -p "Install mpd/ncmpcpp[y/n]? "
if [ "$REPLY" == "y" ]; then
    powerpill -S --noconfirm mpd ncmpcpp mpc
    gpasswd -a mpd users
    cp /etc/mpd.conf.example /etc/mpd.conf
    mkdir /var/lib/mpd/music
    sed -i 's|#music_directory.*$|music_directory "/var/lib/mpd/music"|1' /etc/mpd.conf
    touch /var/lib/mpd/db
    touch /var/lib/mpd/mpdstate
    touch /var/run/mpd/mpd.pid
    touch /var/log/mpd/mpd.log
    touch /var/log/mpd/mpd.error
    chown -R mpd:mpd /var/lib/mpd
    chown -R mpd:mpd /var/run/mpd
    chown -R mpd:mpd /var/log/mpd
    echo -en "$blue :: Completed :: $default\n"
fi

#------Install Xmonad---------#
read -p "Install xmonad[y/n]? "
if [ "$REPLY" == "y" ]; then
    chmod -R 777 /var/abs # Again, dont ask... :)
    yaourt -S --noconfirm haskell-x11-darcs
    yaourt -S --noconfirm xmonad-darcs
    yaourt -S --noconfirm xmonad-contrib-darcs
    pacman -S --noconfirm xmobar
    mkdir /home/$USERNAME/.xmonad
    chown $USERNAME:users /home/$USERNAME/.xmonad
    echo -en "$blue :: Completed :: $default\n"
fi

#-------Install autofs--------#
read -p "Install autofs[y/n]? "
if [ "$REPLY" == "y" ]; then
    pacman -S --noconfirm autofs
    blkid
    sleep 7
    vi /etc/autofs/auto.misc
    vi /etc/autofs/auto.master
    echo -en "$blue Add autofs4 to modules and autofs to daemons $default"
    sleep 5
    vi /etc/rc.conf
    echo -en "$blue :: Completed :: $default\n"
fi

#--------Reboot System---------#
read -p "Reboot system (recommended) [y/n]? "
if [ "$REPLY" == "y" ]; then
    reboot
else
    exit
fi

Offline

#500 2009-09-04 06:59:31

Dieter@be
Forum Fellow
From: Belgium
Registered: 2006-11-05
Posts: 2,001
Website

Re: Post your handy self made command line utilities

brenix wrote:

Not sure if anyone would be interested, but i've created a small script that I use right after I (re)install Arch. It's a post-install script that is somewhat based off what is done on the wiki (adding users, installing xorg, etc). Since I tend to install arch on numerous machines, this has came in very handy..

Note: It's a bit messy. The script installs random things at some times, just cause I was too lazy to move them somewhere else. Take a look for yourself.
(...)

FYI: http://wiki.archlinux.org/index.php/Off … _Procedure


< Daenyth> and he works prolifically
4 8 15 16 23 42

Offline

Board footer

Powered by FluxBB