Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

Compiling GNU sed 4.1.4 on Mac OS X

path='
/usr/local/bin 
/usr/local/sbin
/usr/local/lib
/usr/local/include
/usr/local/man
/usr/bin
/bin
/usr/sbin
/sbin
'

path="$(printf "%s" "${path// /}" | /usr/bin/tr '\n' ':' | /usr/bin/sed -E 's/^:|:$//g')"

printf "%s\n" "$path" | tr ':' '\n'

export PATH="${path}"


cd ~/Desktop

curl -L -O http://ftp.gnu.org/gnu/sed/sed-4.1.4.tar.gz
cd ~/Desktop/sed-4.1.4

# cf. Compiling GNU coreutils on Mac OS X, 
# http://codesnippets.joyent.com/posts/show/1799
./configure --prefix=/usr/local/gnucoreutils
  
make

/usr/bin/sudo /usr/bin/make install



ls -l /usr/local/gnucoreutils/bin/sed
/usr/local/gnucoreutils/bin/sed --version
man /usr/local/gnucoreutils/man/man1/sed.1

/usr/bin/sudo /bin/ln -is /usr/local/gnucoreutils/bin/sed /usr/local/bin/gnused

# use GNU sed with case insensitive option
echo Tool | sed 's/[Tt]/c/'
echo Tool | gnused 's/t/c/i'


# cf. "Extract title from HTML web page" on http://bosetsu.org/pub/docs/shell_cheatsheet.html
curl -L -s http://codesnippets.joyent.com/posts/show/1835 | \
     gnused -n 's/.*<[tT][iI][tT][lL][eE]>\(.*\)<\/[tT][iI][tT][lL][eE]>.*/\1/p;T;q'

# cf. http://www.pixelbeat.org/cmdline.html
curl -L -s http://codesnippets.joyent.com/posts/show/1835 | \
     gnused -n 's/.*<title>\(.*\)<\/title>.*/\1/ip;T;q'

Handling single quotes in Bash

man 2>/dev/null bash | less -p 'Quoting'
man 2>/dev/null bash | less -p "Words of the form \\$'string'"
man 2>/dev/null bash | less -p 'single quote'


echo '\''

echo $'\''
echo $'\x27'
echo $'\047'
echo "'"

echo 'str1'"'"'str2'  # 'str1' + "'" + 'str2'

echo $'single quote \' & double quote "' | sed $'s/& /\\\n/'

str="str's"
echo "${str//\'/''}"

Remove leading zeros via parameter expansion

# cf. http://codesnippets.joyent.com/posts/show/1816
i=004555
printf "%s\n" "${i}"
printf "%s\n" "${i#"${i%%[!0]*}"}"

i="${i#"${i%%[!0]*}"}"
printf "%s\n" "${i}"

Using external variables in awk

See: Accessing external variable in AWK and SED
var="BASH"; echo "unix scripting" | awk '{gsub(/unix/,"'"${var}"'"); print}'
var="BASH"; echo "unix scripting" | awk '{gsub(/unix/,"'"$(echo ${var})"'"); print}'
var="BASH"; echo "unix scripting" | awk -v v="$var" '{sub(/unix/,v); print}'

Basic examples of using associative arrays in awk

# example 1

text='Jex Mon clerk 12001
Aji Tue sales 13003
Jex Wed clerk 13123
Salna Thu sales 34000
Aji Mon sales 13123'

# count the number of occurrences of each "first field"
echo "$text" | awk '{count[$1]++}END{for(j in count) print j,count[j]}'

# sum up the fourth field
echo "$text" | awk '{arr[$1]+=$4} END {for (i in arr) {print i,arr[i]}}'

# both in one line
echo "$text" | awk '{a[$1]++;b[$1]=b[$1]+$NF}END{for (i in a) print i,a[i],b[i]}' 


# example 2

awk -F "|" 'NR > 1  {
    if (n[$1] == $1) {
        r1[$1] = r1[$1] "+" $2
        r2[$1] = r2[$1] "+" $3

    } else {
        n[$1] = $1
        r1[$1] = $2
        r2[$1] = $3

    }
}

END {
    for (i in n) {
            printf "%s [Round1={%s}, Round2={%s}]\n", n[i], r1[i], r2[i]
    }
}'   < <( 
cat <<-'EOF'
Name|Round1|Round2
JSingh|0|20
Vis|50|0
KKR|20|20
JSingh|10|40
Vis|50|20
KKR|40|10
JSingh|40|60
Vis|30|20
KKR|90|20
JSingh|0|60
Vis|20|20
KKR|50|50
EOF
)


References:

- Associative array in awk (example 1)
- Print individual records using awk array - bash (example 2)
- Arrays in awk
- Working with Arrays in awk

Modify every element of a Bash array without looping

See: Messing with arrays in bash
orig=( foo bar baz )

# append "foo" to every array item
array=( foo bar baz )
array=( "${array[@]/%/foo}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# replace last char "r" with "foo"
array=( foo bar baz )
array=( "${array[@]/%r/foo}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# prepend "foo" to every array item
array=( foo bar baz )
array=( "${array[@]/#/foo}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# replace "ba" at the beginning with "foo"
array=( foo bar baz )
array=( "${array[@]/#ba/foo}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# replace any array item matching "b*" with "foo"
array=( foo bar baz )
array=( "${array[@]/%b*/foo}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# replace any array item matching "*z" with "foo"
array=( foo bar baz )
array=( "${array[@]/#*z/foo}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# replace any array item matching "*a*" with "foo"
array=( foo bar baz )
#array=( "${array[@]/%*a*/foo}" )
array=( "${array[@]/#*a*/foo}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# delete a single leading or trailing space from any array item 
# cf. http://codesnippets.joyent.com/posts/show/1816
array=( " foo" "bar " baz )
array=( "${array[@]/# /}" )
array=( "${array[@]/% /}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# further Bash array tips
# for positional parameters also see: 
# http://codesnippets.joyent.com/posts/show/1706

# get the first array item
array=( foo bar baz )
array=( "${array[@]:0:1}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# get the last array item
array=( foo bar baz )
array=( "${array[@]: -1}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# get all array items after the first one
array=( foo bar baz )
array=( "${array[@]:1}" )
echo "${orig[@]}"$'\n'"${array[@]}"


# get the second array item
array=( foo bar baz )
array=( "${array[@]:1:1}" )
echo "${orig[@]}"$'\n'"${array[@]}"

List & delete Safari history

# for PlistBuddy see: http://codesnippets.joyent.com/posts/show/1484

# list Safari history
function lsh() {
   /usr/libexec/PlistBuddy -c Print ~/Library/Safari/History.plist | \
      /usr/bin/awk '/^[[:space:]]+= /{sub( /^[[:space:]]+=[[:space:]]+/,""); print}' | \
      sed -E -n -e 's/^(.{1,100}).*$/\1/' -e '1!G;h;$p' | /usr/bin/nl
      #/usr/bin/sed -n '1!G;h;$p' | /usr/bin/nl
      #/usr/bin/awk '!x[$0]++' | /usr/bin/sed -n '1!G;h;$p' | /usr/bin/nl
      #/usr/bin/sort -u | /usr/bin/nl
   return 0
}

lsh


# delete Safari history except ...
# ... for those domains specified by an egrep regex

function dshe() {

   declare array_indices historyplistfile index regex

   regex="${1:-$'\777'}"   # delete entire history if there is no argument $1; for \777 see man ruby
   historyplistfile="${HOME}/Library/Safari/History.plist"

   array_indices="$(/usr/libexec/PlistBuddy -c print "${historyplistfile}" | /usr/bin/awk '/^[[:space:]]+= /{x++;print x-1,$0}' | \
       /usr/bin/egrep -iv "${regex}" | /usr/bin/awk '{print $1}' | /usr/bin/sort -rn)"

:<<-'COMMENT'
   # test
   for index in ${array_indices}; do 
      echo $index; 
      #/usr/libexec/PlistBuddy -c "Print :WebHistoryDates:'${index}'" "${historyplistfile}" 
      /usr/libexec/PlistBuddy -c "Print :WebHistoryDates:'${index}':title" "${historyplistfile}" 
   done
COMMENT

   for index in ${array_indices}; do 
      /usr/libexec/PlistBuddy -c "Delete :WebHistoryDates:'${index}'" "${historyplistfile}" 
   done

   /usr/libexec/PlistBuddy -c save "${historyplistfile}" &>/dev/null

   return 0

}


lsh
dshe unix
lsh
dshe
lsh

List & delete Safari cookies

# for PlistBuddy see: http://codesnippets.joyent.com/posts/show/1484

# list Safari cookies
function lsc() {
   /usr/libexec/PlistBuddy -c print ~/Library/Cookies/Cookies.plist | \
      /usr/bin/awk '/^[[:space:]]+Domain = /{sub( /^[[:space:]]+Domain =[[:space:]]+/,""); print}' | \
      /usr/bin/sort -u | /usr/bin/nl
      #/usr/bin/awk '!x[$0]++' | /usr/bin/sed -n '1!G;h;$p' | /usr/bin/nl
   return 0
}

lsc


# delete Safari cookies except ...
# ... for those domains specified by an egrep regex

/usr/libexec/PlistBuddy -c Print ~/Library/Cookies/Cookies.plist
/usr/libexec/PlistBuddy -c 'Print :0' ~/Library/Cookies/Cookies.plist
/usr/libexec/PlistBuddy -c 'Print :1' ~/Library/Cookies/Cookies.plist


function dsce() {

   declare array_indices cookiesplistfile index regex

   regex="${1:-$'\777'}"   # delete all cookies if there is no argument $1; for \777 see man ruby
   cookiesplistfile="${HOME}/Library/Cookies/Cookies.plist"

   array_indices="$(/usr/libexec/PlistBuddy -c print "${cookiesplistfile}" | /usr/bin/awk '/Domain = /{x++;print x-1,$0}' | \
       /usr/bin/egrep -iv "${regex}" | /usr/bin/awk '{print $1}' | /usr/bin/sort -rn)"

:<<-'COMMENT'
   # test
   for index in ${array_indices}; do 
      echo $index; 
      #/usr/libexec/PlistBuddy -c "Print :'${index}'" "${cookiesplistfile}" 
      /usr/libexec/PlistBuddy -c "Print :'${index}':Domain" "${cookiesplistfile}" 
   done
COMMENT

   for index in ${array_indices}; do 
      /usr/libexec/PlistBuddy -c "Delete :'${index}'" "${cookiesplistfile}" 
   done

   /usr/libexec/PlistBuddy -c save "${cookiesplistfile}" &>/dev/null

   return 0

}


lsc

dsce 'xxx.com|xxx.org'

lsc

Get network service information on Mac OS X

# cf. http://www.macosxhints.com/article.php?story=20050214200529336

function network_service_name() {

   SERVICE_GUID=$(printf "open\nget State:/Network/Global/IPv4\nd.show" | \
      /usr/sbin/scutil | /usr/bin/awk '/PrimaryService/{print $3}')

   SERVICE_NAME=$(printf "open\nget Setup:/Network/Service/${SERVICE_GUID}\nd.show" | \
      /usr/sbin/scutil | /usr/bin/awk -F': ' '/UserDefinedName/{print $2}')

   echo $SERVICE_NAME

   return 0

}


network_service_name

# cf. systemsetup & networksetup, http://codesnippets.joyent.com/posts/show/1691
/usr/bin/sudo /usr/sbin/networksetup -getinfo "$(network_service_name)"


# further network management command line tools:
# - http://turin.nss.udel.edu/programming/ncutil/
# - http://turin.nss.udel.edu/programming/ncutil/UsersGuide/index.html
# - http://www.julien-jalon.org/sysprefs/index.html

app2dock

An exercise in using PlistBuddy.

dockplistfile="${HOME}/Library/Preferences/com.apple.dock.plist"

cp -ip "${dockplistfile}" "${dockplistfile}.orig"

plutil -convert xml1 -o /dev/fd/1 "${dockplistfile}" | /usr/bin/pl
plutil -convert xml1 -o ~/Desktop/com.apple.dock.plist "${dockplistfile}"
open -e ~/Desktop/com.apple.dock.plist


# get an example entry from $dockplistfile (last application in the Dock)
# cf. http://codesnippets.joyent.com/posts/show/1814

num_apps_dock=$(/usr/libexec/PlistBuddy -c "Print :persistent-apps" "${dockplistfile}" | awk -F '=' '/CFURLString = /{print $2}' | wc -l)
echo ${num_apps_dock}

/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${num_apps_dock}'" "${dockplistfile}" 
#/usr/libexec/PlistBuddy -c "Print :persistent-apps:${num_apps_dock}" "${dockplistfile}" 

/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${num_apps_dock}':tile-data:file-data:_CFURLString" "${dockplistfile}"


open /bin/bash


# we will first create an example entry step by step
# note: persistent-apps is an array that stores dictionaries

dockplistfile="${HOME}/Library/Preferences/com.apple.dock.plist"

# get a free array index number (that is, the last + 1 array index)
free_num_apps_dock=$(( 1 + $(/usr/libexec/PlistBuddy -c "Print :persistent-apps" "${dockplistfile}" | awk -F '=' '/CFURLString = /{print $2}' | wc -l) ))
echo ${free_num_apps_dock}

# add a dictionary to the persistent-apps array at array index ${free_num_apps_dock}
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}' dict" "${dockplistfile}" 

# print the dictionay in the persistent-apps array at array index ${free_num_apps_dock}
/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 

# add a dictionary named "tile-data" to the previously added dictionary 
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data dict" "${dockplistfile}" 

/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 

# add the dictionary 'file-data' to the dictionary 'tile-data'
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data dict" "${dockplistfile}" 

/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 

# add key - value pairs to the file-data dictionary
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:thisIsAKey string 'this is a string value'" "${dockplistfile}" 
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:_CFURLString string '/path/to/app'" "${dockplistfile}" 
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:_CFURLStringType integer 0" "${dockplistfile}" 

/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 

# delete the dictionay in the persistent-apps array at array index ${free_num_apps_dock}
/usr/libexec/PlistBuddy -c "Delete :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 

# print all dictionaries of the persistent-apps array
/usr/libexec/PlistBuddy -c "Print :persistent-apps" "${dockplistfile}" 


# short version
dockplistfile="${HOME}/Library/Preferences/com.apple.dock.plist"
free_num_apps_dock=$(( 1 + $(/usr/libexec/PlistBuddy -c "Print :persistent-apps" "${dockplistfile}" | awk -F '=' '/CFURLString = /{print $2}' | wc -l) ))
echo ${free_num_apps_dock}
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:thisIsAKey string 'this is a string value'" "${dockplistfile}" 
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:_CFURLString string '/path/to/app'" "${dockplistfile}" 
/usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:_CFURLStringType integer 0" "${dockplistfile}" 
/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 
/usr/libexec/PlistBuddy -c "Delete :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 
/usr/libexec/PlistBuddy -c "Print :persistent-apps" "${dockplistfile}" 


:<<-'COMMENT'
# example entry
Dict {
    tile-data = Dict {
        file-data = Dict {
            thisIsAKey = this is a string value
            _CFURLString = /path/to/app
            _CFURLStringType = 0
        }
    }
}

COMMENT



#-----------------------------------------------------------------------------



# app2dock
# allows case insensitive name of application as input
# uses lsregister & egrep -i

# lsregister
/usr/bin/sudo /bin/ln -is $(/usr/bin/locate *lsregister | /usr/bin/head -n 1) /bin/lsregister 

function app2dock() {
   declare appname dockplistfile free_num_apps_dock path
   dockplistfile="${HOME}/Library/Preferences/com.apple.dock.plist"

   for appname in "${@}"; do
      appname="${appname%/}"
      path="$(/bin/lsregister -dump | /usr/bin/egrep -i -m 1 "path: +.*\/[^\/]*${appname}[^\/]*\.app$" | \
                /usr/bin/sed -E 's/^[[:space:]]+path:[[:space:]]+//')"
      if [[ -z "${path}" ]]; then echo "No such application: ${appname}"; continue; fi
      path="${path%/}"
      if [[ ! -d "${path}" ]] || [[ "${path}" == "${path%.app}" ]]; then echo "Argument error: ${path}"; continue; fi
      free_num_apps_dock=$(( 1 + $(/usr/libexec/PlistBuddy -c "Print :persistent-apps" "${dockplistfile}" | \
             /usr/bin/awk -F '=' '/CFURLString = /{print $2}' | /usr/bin/wc -l) ))
      #echo ${free_num_apps_dock}
      /usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:_CFURLString string '${path}'" "${dockplistfile}" 
      /usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:_CFURLStringType integer 0" "${dockplistfile}" 
      #/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 
      /usr/libexec/PlistBuddy -c save "${dockplistfile}" &>/dev/null
   done

   /usr/bin/killall -HUP Dock
   return 0
}



# app2dock_fp
# only allows full file path to application as input

function app2dock_fp() {
   declare dockplistfile free_num_apps_dock path
   dockplistfile="${HOME}/Library/Preferences/com.apple.dock.plist"

   for path in "${@}"; do
      path="${path%/}"
      if [[ ! -d "${path}" ]] || [[ "${path}" == "${path%.app}" ]]; then echo "Argument error: ${path}"; continue; fi
      free_num_apps_dock=$(( 1 + $(/usr/libexec/PlistBuddy -c "Print :persistent-apps" "${dockplistfile}" | \
             /usr/bin/awk -F '=' '/CFURLString = /{print $2}' | /usr/bin/wc -l) ))
      #echo ${free_num_apps_dock}
      /usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:_CFURLString string '${path}'" "${dockplistfile}" 
      /usr/libexec/PlistBuddy -c "Add :persistent-apps:'${free_num_apps_dock}':tile-data:file-data:_CFURLStringType integer 0" "${dockplistfile}" 
      #/usr/libexec/PlistBuddy -c "Print :persistent-apps:'${free_num_apps_dock}'" "${dockplistfile}" 
      /usr/libexec/PlistBuddy -c save "${dockplistfile}" &>/dev/null

   done

   /usr/bin/killall -HUP Dock
   return 0
}



# remove_app_from_dock
# allows case insensitive name of application as input

function remove_app_from_dock() {

   declare appname dockplistfile nums=""

   dockplistfile="${HOME}/Library/Preferences/com.apple.dock.plist"

   for appname in "${@}"; do

      appname="${appname%/}"

      nums=""
      nums=$(/usr/libexec/PlistBuddy -c "Print :persistent-apps" "${dockplistfile}" | /usr/bin/awk -F '=' '/CFURLString = /{print $2}' | \
            /usr/bin/nl | /usr/bin/egrep -i "${appname}" | /usr/bin/awk '{print $1}' | /usr/bin/sort -rn)

      if [[ -z "${nums}" ]]; then echo "No application: ${appname} found in the Dock."; continue; fi

      for num in ${nums}; do
         /usr/libexec/PlistBuddy -c "Delete :persistent-apps:'${num}'" "${dockplistfile}" 
      done

      # test
      #for num in ${nums}; do
      #   /usr/libexec/PlistBuddy -c "Print :persistent-apps:'${num}'" "${dockplistfile}" 
      #done

      /usr/libexec/PlistBuddy -c save "${dockplistfile}" &>/dev/null

   done

   /usr/bin/killall -HUP Dock

   return 0

}


app2dock_fp /Applications/Chess.app /Applications/Chess.app

app2dock chess grapher

remove_app_from_dock chess grapher