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!)

List the names & version numbers of applications

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


# first rebuild the Launch Services database
lsregister -kill -r -f -all system,local,user     # Mac OS X 10.5
lsregister -kill -r -f -domain local -domain system -domain user


# print the lines between :path ... version: ...
time -p lsregister -dump | sed -E -n -e '/^.+path: .+\.app$/{N;N;N;p;}' | nl
time -p lsregister -dump | sed -E -n -e '/\.app$/{N;N;N;p;}' | nl

time -p lsregister -dump | sed -E -n -e '/path: .+\.app$/,/version:/p' | nl
time -p lsregister -dump | sed -E -n -e '/\.app$/,/version:/p' | nl

time -p lsregister -dump | egrep -A 3 -i "path: +\/.+\\.app$" | nl


# list application paths with lsregister
time -p lsregister -dump | sed -E -n -e '/path: .+\.app$/,/version:/s/^.+path: +(.+\.app)$/\1/p' | nl
time -p lsregister -dump | sed -E -n -e '/\.app$/,/version:/s/^.+path: +(.+\.app)$/\1/p' | nl

# list application names with lsregister
time -p lsregister -dump | sed -E -n -e '/path: .+\.app$/,/version:/s/^.+path: +\/?.*\/([^\/]+\.app)$/\1/p' | nl
time -p lsregister -dump | sed -E -n -e '/\.app$/,/version:/s/^.+path: +\/?.*\/([^\/]+\.app)$/\1/p' | nl

# list version numbers of applications with lsregister
time -p lsregister -dump | sed -E -n -e '/path: +.+\.app$/,/version/s/^.+version: +(.*)$/\1/p' | nl
time -p lsregister -dump | sed -E -n -e '/\.app$/,/version/s/^.+version: +(.*)$/\1/p' | nl


# list the names & version numbers of applications based on lsregister

function lsvers() {

   if [[ "$1" == '-fp' ]]; then     # full path option

      while read -d $'\n' file; do

         path="${file% -*}"
         lsregister_version="${file##*- }"

         mdls_version="$(/usr/bin/mdls -name kMDItemVersion "${path}" 2>/dev/null | \
            /usr/bin/awk -F '"' '/kMDItemVersion/ {print $2}' 2>/dev/null)"
         #mdls_version="$(/usr/bin/mdls -name kMDItemVersion "${path}" 2>/dev/null | \
         #   /usr/bin/awk -F '"' 'END {print $2}' 2>/dev/null)"

         if [[ -n "$mdls_version" ]]; then
            printf "%s\n" "${path}   --   ${mdls_version}"
         else
            printf "%s\n" "${path}   --   ${lsregister_version}"
         fi

done < <(
/bin/lsregister -dump | /usr/bin/egrep -A 3 '^[[:space:]]+path:[[:space:]]+([^[:space:]].*\.app)$' | \
/usr/bin/sed -E -n -e 's/^[[:space:]]+version:[[:space:]]+(.*)$/\1/p' -e 's/^[[:space:]]+path:[[:space:]]+(\/.*\.app)$/\1/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n"
)

   else

      while read -d $'\n' file; do

         path="${file% -*}"
         bname="$(/usr/bin/basename "${path}")"
         lsregister_version="${file##*- }"

         mdls_version="$(/usr/bin/mdls -name kMDItemVersion "${path}" 2>/dev/null | \
            /usr/bin/awk -F '"' '/kMDItemVersion/ {print $2}' 2>/dev/null)"

         if [[ -n "$mdls_version" ]]; then
            printf "%s\n" "${bname}   --   ${mdls_version}"
         else
            printf "%s\n" "${bname}   --   ${lsregister_version}"
         fi

done < <(
/bin/lsregister -dump | /usr/bin/egrep -A 3 '^[[:space:]]+path:[[:space:]]+([^[:space:]].*\.app)$' | \
/usr/bin/sed -E -n -e 's/^[[:space:]]+version:[[:space:]]+(.*)$/\1/p' -e 's/^[[:space:]]+path:[[:space:]]+(\/.*\.app)$/\1/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n"
)

   fi


: <<-'COMMENT'

time -p /bin/lsregister -dump | /usr/bin/egrep -A 3 '^[[:space:]]+path:[[:space:]]+([^[:space:]].*\.app)$' | \
/usr/bin/sed -E -n -e 's/^[[:space:]]+version:[[:space:]]+(.*)$/\1/p' -e 's/^[[:space:]]+path:[[:space:]]+(\/.*\.app)$/\1/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n" | nl

# alternatives with sed pattern matching across several lines (here matching the lines containing: path: ... :version ...)

time -p /bin/lsregister -dump | /usr/bin/sed -E -n -e '/path:.+\.app$/,/version:/s/^.+path: +(\/.+\.app)$|^.+version: +(.+)$/\1\2/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n" | nl

time -p /bin/lsregister -dump | /usr/bin/sed -E -n -e '/path:.+\.app$/,/version:/s/path: +(\/.+\.app)$|version: +(.+)$/\1\2/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n" | nl

time -p /bin/lsregister -dump | /usr/bin/sed -E -n -e '/\.app$/,/version:/s/path: +(\/.+\.app)$|version: +(.+)$/\1\2/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n" | nl

COMMENT


return 0

}


lsvers | nl
lsvers | egrep -i system | nl
lsvers -fp | egrep -i system | nl     # print full paths to applications
lsvers -fp | egrep -i '\/[^\/]*system[^\/]*$' | nl     # print full paths to applications


# check
app="VerifiedDownloadAgent.app"
app="Crash Reporter.app"
app="SyncServer.app"
app="SecurityAgent.app"
app="SystemUIServer.app"

lsregister -dump | egrep -A 3 "${app}$"

path="$(lsregister -dump | grep -A 3 "${app}$" | sed -E -n -e 's/^[[:space:]]+path:[[:space:]]+(\/.*\.app)$/\1/p')"
echo "$path"
mdls -name kMDItemVersion "$path"


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


# list the names and version numbers of specified applications using lsregister
function appversion() {

/bin/lsregister -dump | /usr/bin/egrep -i -A 3 "^[[:space:]]+path:[[:space:]]+\/?.*\/([^\/]*${@}[^\/]*\\.app)$" | \
/usr/bin/sed -E -n -e 's/^[[:space:]]+version:[[:space:]]+(.*)$/\1/p' -e 's/^[[:space:]]+path:[[:space:]]+\/.*\/([^\/]+\.app)$/\1/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s   --   %s\n"


: <<-'COMMENT'

set -- System
echo "${@}"

time -p /bin/lsregister -dump | /usr/bin/egrep -i -A 3 "^[[:space:]]+path:[[:space:]]+\/?.*\/[^\/]*${@}[^\/]*\\.app$" | \
/usr/bin/sed -E -n -e 's/^[[:space:]]+version:[[:space:]]+(.*)$/\1/p' -e 's/^[[:space:]]+path:[[:space:]]+\/.*\/([^\/]+\.app)$/\1/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n" | nl

# alternatives
time -p /bin/lsregister -dump | /usr/bin/egrep -A 3 -i "path: +\/?.*\/[^\/]*${@}[^\/]*\\.app$" | /usr/bin/sed -E -n \
-e 's/version: +(.*)$/\1/p' -e 's/path: +\/?.*\/([^\/]+\.app)$/\1/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n" | nl

time -p /bin/lsregister -dump | /usr/bin/egrep -A 3 -i " +\/?.*\/[^\/]*${@}[^\/]*\\.app$" | /usr/bin/sed -E -n \
-e 's/version: +(.*)$/\1/p' -e 's/path: +\/?.*\/([^\/]+\.app)$/\1/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n" | nl


# alternative with sed pattern matching across several lines
# here: matching the lines between: path: ... :version ...

time -p /bin/lsregister -dump | /usr/bin/egrep -A 3 -i "path: +\/?.*\/[^\/]*${@}[^\/]*\\.app$" | /usr/bin/sed -E -n \
-e '/\.app$/,/version:/s/path: +\/?.*\/([^\/]+\.app)$|version: +(.+)$/\1\2/p' | \
/usr/bin/sed 's/ /\\ /g' | /usr/bin/xargs -n 2 printf "%s - %s\n" | nl

COMMENT

return 0
}


appversion mail
appversion finder
appversion safari

appversion system
appversion uiserver
appversion server
appversion window


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


# list names & mdls version numbers of applications (based on mdfind & com.apple.application-bundle)
function lsmdvers() {

   if [[ "$1" == '-fp' ]]; then     # full path option

      while read -d $'\000' file; do

         mdls_version="$(/usr/bin/mdls -name kMDItemVersion "${file}" 2>/dev/null | \
            /usr/bin/awk -F '"' '/kMDItemVersion/ {print $2}' 2>/dev/null)"

         if [[ -n "$mdls_version" ]]; then
            printf "%s\n" "${file}   --   ${mdls_version}"
         else
            printf "%s\x21\n" "${file}   --   No mdls version number specified"
         fi

      done < <(/usr/bin/mdfind -0 'kMDItemContentTypeTree == "com.apple.application-bundle"wc')

   else

      while read -d $'\000' file; do

         bname="$(/usr/bin/basename "${file}")"

         mdls_version="$(/usr/bin/mdls -name kMDItemVersion "${file}" 2>/dev/null | \
            /usr/bin/awk -F '"' '/kMDItemVersion/ {print $2}' 2>/dev/null)"

         if [[ -n "$mdls_version" ]]; then
            printf "%s\n" "${bname}   --   ${mdls_version}"
         else
            printf "%s\x21\n" "${bname}   --   No mdls version number specified"
         fi

      done < <(/usr/bin/mdfind -0 'kMDItemContentTypeTree == "com.apple.application-bundle"wc')

   fi

   return 0

}


lsmdvers | nl
lsmdvers -fp | nl    # print full paths to applications

lsmdvers | grep -i system | nl && echo && lsvers | grep -i system | nl



# list the names and version numbers of specified applications using mdfind & com.apple.application-bundle
function appmdversion() {

   if [[ "$1" == '-fp' ]]; then     # full path option

      while read -d $'\000' file; do

         mdls_version="$(/usr/bin/mdls -name kMDItemVersion "${file}" 2>/dev/null | \
            /usr/bin/awk -F '"' '/kMDItemVersion/ {print $2}' 2>/dev/null)"

         if [[ -n "$mdls_version" ]]; then
            printf "%s\n" "${file}   --   ${mdls_version}"
         else
            printf "%s\x21\n" "${file}   --   No mdls version number specified"
         fi

      done < <(/usr/bin/mdfind -0 "kMDItemContentTypeTree == 'com.apple.application-bundle'wc && kMDItemDisplayName == '*${2:-*}*'wc")

   else

      while read -d $'\000' file; do

         bname="$(/usr/bin/basename "${file}")"

         mdls_version="$(/usr/bin/mdls -name kMDItemVersion "${file}" 2>/dev/null | \
            /usr/bin/awk -F '"' '/kMDItemVersion/ {print $2}' 2>/dev/null)"

         if [[ -n "$mdls_version" ]]; then
            printf "%s\n" "${bname}   --   ${mdls_version}"
         else
            printf "%s\x21\n" "${bname}   --   No mdls version number specified"
         fi

      done < <(/usr/bin/mdfind -0 "kMDItemContentTypeTree == 'com.apple.application-bundle'wc && kMDItemDisplayName == '*${@:-*}*'wc")

   fi

   return 0

}


appmdversion play | nl
appmdversion -fp play | nl   # print full paths to applications

appversion play && echo && appmdversion play


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


# experimental

function cmdversion() {

declare cmd last_modified vers

while [ $# -gt 0 ]; do

   cmd="$(/usr/bin/which ${1})"   # get the full cmd path

   # cmd was not found in $PATH
   if [[ -n "$(echo "$cmd" | /usr/bin/egrep "^no +${1} +in ")" ]]; then echo; echo "${cmd}"; echo; shift; continue; fi
   #if [[ -n "$(echo "$cmd" | /usr/bin/egrep '^no +[^[:space:]]+ +in ')" ]]; then echo; echo "${cmd}"; echo; shift; continue; fi


   # handle special cases such as ls, echo, ...
   if [[ "${1##*/}" == "ls" ]] || [[ "${1##*/}" == "echo" ]] || [[ "${1##*/}" == "getopt" ]]; then
      vers="$(/usr/bin/egrep -ao '(.{0,10}[Vv]ersion:? +"?[\.\_[:digit:]]+"?.{0,15}|.{0,10}[Vv]\.? +"?[\.\_[:digit:]]+"?.{0,15})' "${cmd}")"
      last_modified="$(/usr/bin/stat -f $'last modified:   %Sm\n' "${cmd}")"
      #printf "\e[1m%s\e[m (guess):\n%s\n" "${cmd}" "${vers}"
      printf "\e[1m%s\e[m (guess):\n%s\n%s\n" "${cmd}" "${vers}" "${last_modified}"
      shift
      continue
   fi

   if [[ "${1##*/}" == "python" ]]; then
      vers="$(${cmd} -V 2>&1)"
      printf "\e[1m%s\e[m:\n%s\n" "${cmd}" "${vers}"
      shift
      continue
   fi

   # cases that require sudo
   if [[ "${1##*/}" == "fibreconfig" ]]; then
      vers="$(/usr/bin/sudo ${cmd} --version 2>&1)"
      printf "\e[1m%s\e[m:\n%s\n" "${cmd}" "${vers}"
      shift
      continue
   fi


   if [[ -n "$(${cmd} --version 2>/dev/null)" ]]; then
      vers="$(${cmd} --version)"
      printf "\e[1m%s\e[m:\n%s\n" "${cmd}" "${vers}"

   elif [[ -n "$(${cmd} -version 2>/dev/null)" ]]; then
      vers="$(${cmd} -version)"
      printf "\e[1m%s\e[m:\n%s\n" "${cmd}" "${vers}"

   elif [[ -n "$(${cmd} --version 2>&1 | /usr/bin/egrep -ao '([Vv]ersion:? *"?[\.\_[:digit:]]+"?|[Vv]\.? +"?[\.\_[:digit:]]+"?)')" ]]; then
      vers="$(${cmd} --version 2>&1)"
      printf "\e[1m%s\e[m:\n%s\n" "${cmd}" "${vers}"

   elif [[ -n "$(${cmd} -version 2>&1 | /usr/bin/egrep -ao '([Vv]ersion:? *"?[\.\_[:digit:]]+"?|[Vv]\.? +"?[\.\_[:digit:]]+"?)')" ]]; then
      vers="$(${cmd} -version 2>&1)"
      printf "\e[1m%s\e[m:\n%s\n" "${cmd}" "${vers}"

   elif [[ -n "$(/usr/bin/egrep -ao '([Vv]ersion:? +"?[\.\_[:digit:]]+"?|[Vv]\.? +"?[\.\_[:digit:]]+"?)' "${cmd}" 2>/dev/null) 2>/dev/null)" ]]; then
      vers="$(/usr/bin/egrep -ao '(.{0,10}[Vv]ersion:? +"?[\.\_[:digit:]]+"?.{0,15}|.{0,10}[Vv]\.? +"?[\.\_[:digit:]]+"?.{0,15})' "${cmd}")"
      #vers="$(/usr/bin/egrep -ao '(.{0,30}[Vv]ersion:? +"?[\.\_[:digit:]]+"?.{0,30}|.{0,30}[Vv]\.? +"?[\.\_[:digit:]]+"?.{0,30})' "${cmd}")"
      #vers="$(/usr/bin/egrep -ao '([Vv]ersion:? +"?[\.\_[:digit:]]+"?|[Vv]\.? +"?[\.\_[:digit:]]+"?)' "${cmd}")"

      last_modified="$(/usr/bin/stat -f $'last modified:   %Sm\n' "${cmd}")"

      if [[ -z "${vers}" ]]; then 
         printf "\e[1m%s\e[m:\n%s\n" "${cmd}" "${last_modified}"
         shift
         continue
      fi

      #printf "\e[1m%s\e[m (guess):\n%s\n" "${cmd}" "${vers}"
      printf "\e[1m%s\e[m (guess):\n%s\n%s\n" "${cmd}" "${vers}" "${last_modified}"

   fi

   shift

done

return 0
}


cmdversion bash
cmdversion /bin/bash

cmdversion sh java sed ls echo printf tr

cmdversion rm srm rmdir unlink kill killall

cmdversion read stat chown w tcl tk getopt getopts symlink ln locate

cmdversion chmod cp dd ed ssh

cmdversion bzcat openssl cat open alias uuidgen bc apropos man perl python ruby

cmdversion /sbin/fibreconfig


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


# list the version numbers of dynamically loaded kernel extensions
man kextstat   
/usr/sbin/kextstat | /usr/bin/sed -E -n -e 's/^([[:space:]]+[^[:space:]]+){5}[[:space:]]+([^[:space:]]+)[[:space:]]+\(([^[:space:]]+)\).*$/\2  --  \3/p'

Counting lines

# create a test file
testfile="${HOME}/Desktop/testfile.txt"
jot -b 'sample text' 10 | cat -n > "$testfile"
printf "%s\n" >> "$testfile"                                 # add an empty line
printf "%s\n\r\n\r\n\r\r\n" "sample text" >> "$testfile"     # add lines with '\r\n' as line separators 
printf "%s" "sample text" >> "$testfile"                     # add a last line without a terminating '\n'       

open -e "$testfile"

function odcfile() {
/usr/bin/od -A n -c < "$@" | /usr/bin/sed -E -e 's/^[[:space:]]{11}//' \
       -e s/[[:space:]]{4}/$'\001'/g \
       -e 's/[[:space:]]+//g' | \
       /usr/bin/tr -d '\n' | /usr/bin/tr '\001' ' ' | \
       /usr/bin/sed -e s/\\\\n/$'\\\\\\n\\\n'/g 

return 0
}

odcfile "$testfile"



# wc -l
wc -l < "$testfile"     # returns the number of '\n' characters

# ed 
ed -s "$testfile" <<< '='     # all lines

# cat
cat -n "$testfile" | awk 'END {print $1}'   # all lines


# grep
grep -c $'\n' "$testfile"                 # all lines
grep -c '^.*$' "$testfile"                # all lines
#grep -c $'\000' "$testfile"
grep -c $'\r$' "$testfile"                # all lines ending with \r\n
grep -c '^[[:space:]]*$' "$testfile"      # all blank lines
grep -cv '^[[:space:]]*$' "$testfile"     # all non-blank lines


# sed
sed -n '$=' "$testfile"                          # all lines
sed -n /$'\r'$/= "$testfile" | wc -l             # all lines ending with \r\n
sed -n '/^[[:space:]]*$/=' "$testfile" | wc -l   # all blank lines
sed -n '/[^[:space:]]/=' "$testfile" | wc -l     # all non-blank lines


# awk
awk 'END {print NR}' "$testfile"                           # all lines
awk '{x++} END {print x}' "$testfile"                      # all lines
awk '/^.*$/ {++x} END {print x}' "$testfile"               # all lines
awk '/\r$/ {++x} END {print x}' "$testfile"                # all lines ending with \r\n
awk '/^[[:space:]]*$/ {++x} END {print x}' "$testfile"     # all blank lines
awk '/[^[:space:]]/ {++x} END {print x}' "$testfile"       # all non-blank lines


# nl
nl "$testfile" | awk 'END {print $1}'
nl -b a "$testfile" | awk 'END {print $1}'   # including empty lines


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


# counting the lines of files in a directory

DIR=/path/to/dir

find "$DIR" -type f -name "*.txt" -print0 | xargs -0 wc -l

find "$DIR" -type f -name "*.txt" -print0 | xargs -0 sed -n '$='

find "$DIR" -type f -name "*.txt" -print0 | xargs -0 awk 'END {print NR}'
find "$DIR" -type f -name "*.txt" -print0 | xargs -0 awk '{x++} END {print x}'
find "$DIR" -type f -name "*.txt" -print0 | xargs -0 awk '/\r$/ {++x} END {print x}'
find "$DIR" -type f -name "*.txt" -print0 | xargs -0 awk '/^[[:space:]]*$/ {++x} END {print x}'
find "$DIR" -type f -name "*.txt" -print0 | xargs -0 awk '/[^[:space:]]/ {++x} END {print x}'


# rather slow, but without the "Argument list too long" issue: /usr/sbin/sysctl kern.argmax
# cf. http://www.onlamp.com/pub/a/bsd/2002/03/14/FreeBSD_Basics.html

declare -i linecnt=0
while read -d $'\0' file; do
   #linecnt=$((${linecnt} + $(/usr/bin/sed -n '$=' "${file}")))
   let "linecnt += $(/usr/bin/sed -n '$=' "${file}")"   # cf. help let
done < <(/usr/bin/find "$DIR" -type f -name "*.txt" -print0)

echo $linecnt

Delete carriage returns & newlines with sed

# delete newlines

printf "a\nb\nc\nd\ne\nf" | sed -n -e 'l'
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n//g; ta'

printf "a\n\nb" | sed -n -e 'l'
printf "a\n\nb" | sed -E -e :a -e '$!N; s/\n//g; ta' | sed -n -e 'l'
printf "a\n\nb" | sed -E -e :a -e '$!N; s/\n$//g; ta' | sed -n -e 'l'
printf "a\n\n\n\n\n\nb" | sed -E -e :a -e '$!N; s/\n$//g; ta' | sed -n -e 'l'


# delete carriage returns

printf "he\r\rllo\n" | sed -n -e 'l'
printf "he\r\rllo\n" | sed -e s/$'\r'//g | sed -n -e 'l'
printf "he\r\rllo\n" | sed -e s/$'\r\r'/$'\r'/g | sed -n -e 'l'

CR=$'\r'
printf "hello\r\r\n" | sed "s/$CR$CR$/$CR/g" | sed -n -e 'l'


# alternatives

printf "a\nb\nc\nd\ne\nf" | tr -d '\n'

# cf. http://linux.dsplabs.com.au/rmnl-remove-new-line-characters-tr-awk-perl-sed-c-cpp-bash-python-xargs-ghc-ghci-haskell-sam-ssam-p65/
while read -d $'\n'; do echo -n "${REPLY} "; done < <((printf "a\nb\nc\nd\ne\nf"))
while read -d $'\n'; do printf "%s   " "${REPLY}"; done < <((printf "a\nb\nc\nd\ne\nf"))

xargs echo < <((printf "a\nb\nc\nd\ne\nf"))
xargs printf "%s " < <((printf "a\nb\nc\nd\ne\nf"))

printf "a\nb\nc\nd\ne\nf" | /usr/bin/paste -s -d ' ' -     # cf. man paste

# delete newlines in-place (also see below)
vim -e -s +':%j' +'w!' +'qa!' /path/to/file

# insert newlines again
printf "%s\n" "hello" | sed -e s/l/$'\\\n'/g | sed -n -e 'l'
printf "%s\n" "hello" | sed -E s/\(l\)/\\1$'\\\n'/g | sed -n -e 'l'


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


# converting between \n and \n\r

# cf. also flip, http://ccrma.stanford.edu/~craig/utility/flip/ and 
# http://codesnippets.joyent.com/posts/show/1660


# convert \n into \r\n
printf "a\nb\nc\nd\ne\nf\n"
printf "a\nb\nc\nd\ne\nf\n" | sed -n -e 'l'

printf "a\nb\nc\nd\ne\nf\n" | sed s/$/$'\r'/
printf "a\nb\nc\nd\ne\nf\n" | sed s/$/$'\r'/ | sed -n -e 'l'

printf "a\nb\n\n\n\n\n\n\n\n\n\n\nc\nd\ne\nf\n" | sed -E -e :a -e '$!N; s/\n$//g; ta' | sed -E s/$/$'\r'/ | sed -n -e 'l'

while read -d $'\n'; do printf "%s\r\n" "${REPLY}"; done < <((printf "a\nb\nc\nd\ne\nf\n"))
while read -d $'\n'; do printf "%s\r\n" "${REPLY}"; done < <((printf "a\nb\nc\nd\ne\nf\n")) | sed -n -e 'l'


# convert \r\n into \n
printf "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\n"
printf "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\n" | sed -n -e 'l'

printf "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\n" | sed s/$'\r'$//
printf "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\n" | sed s/$'\r'$// | sed -n -e 'l'

printf "a\r\nb\r\r\r\r\r\r\r\r\r\r\nc\r\nd\r\ne\r\nf\r\n" | sed s/$'\r'*$// | sed -n -e 'l'
printf "a\r\nb\r\r\r\r\r\r\r\r\r\r\nc\r\nd\r\ne\r\nf\r\n" | sed -E s/$'\r'+$// | sed -n -e 'l'

# lacks a terminating \n though
while read -d $'\r'; do printf "%s" "${REPLY}"; done < <((printf "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\n"))
while read -d $'\r'; do printf "%s" "${REPLY}"; done < <((printf "a\r\nb\r\nc\r\nd\r\ne\r\nf\r\n")) | sed -n -e 'l'


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


# create test files

testfile="${HOME}/Desktop/testfile.txt"
output="${HOME}/Desktop/output.txt"

function createfiles() {

testfile="${HOME}/Desktop/testfile.txt"
output="${HOME}/Desktop/output.txt"

/usr/bin/touch "$output"

#/usr/bin/jot -b 'sample text' 10 | /bin/cat > "$testfile"
/usr/bin/jot -b 'sample text' 10 | /bin/cat -n > "$testfile"
printf "%s\r\n\r\n\r\r\n" "sample text" >> "$testfile"      # append a line with a '\r\n' line separator
printf "%s" "sample text" >> "$testfile"          # append a last line without a terminating '\n'

return 0
}

createfiles


# inspect test file

cat -vet "$testfile"
ed -s "$testfile" <<< $',l'
sed -n -e 'l'  "$testfile"
ruby -n -e 'p $_.to_s' < "$testfile"


function odcfile() {

/usr/bin/od -A n -c < "$@" | /usr/bin/sed -E -e 's/^[[:space:]]{11}//' \
       -e s/[[:space:]]{4}/$'\001'/g \
       -e 's/[[:space:]]+//g' | \
       /usr/bin/tr -d '\n' | /usr/bin/tr '\001' ' ' | \
       /usr/bin/sed -e s/\\\\n/$'\\\\\\n\\\n'/g 

return 0
}


odcfile "$testfile"


# remove newlines "\n"

# create a new file with newline characters replaced with a space
sed -e :a -e '$!N; s/\n/ /g; ta' "$testfile" > "$output"
odcfile "$output"

# same, but in-place
sed -i "" -e :a -e '$!N; s/\n/ /g; ta' "$testfile"
odcfile "$testfile"

createfiles

# delete newlines in-place
sed -i "" -e :a -e '$!N; s/\n//g; ta' "$testfile"
odcfile "$testfile"

createfiles

# alternative for creating a new file without newlines
tr -d '\n' < "$testfile" > "$output"
odcfile "$output"



# delete carriage returns "\r"

# create a new file with carriage returns deleted
sed -e s/$'\r'//g "$testfile" > "$output"
sed -e s/$'\r'$//g "$testfile" > "$output"  # only at line end
odcfile "$output"

# alternative
tr -d '\r' < "$testfile" > "$output"
odcfile "$output"


# delete carriage returns in-place

sed -i "" -e s/$'\r'//g "$testfile" > "$output"
odcfile "$testfile"

createfiles

# cf. http://bash-hackers.org/wiki/doku.php?id=howto:edit-ed (Pitfalls)
ed -s "$testfile" <<< $'H\n,g/\r/s/\r//\n,w'      # delete one carriage return in a line
ed -s "$testfile" <<< $'H\n,g/\r/s/\r//g\n,w'     # delete all carriage returns in a line
ed -s "$testfile" <<< $'H\n,g/\r$/s/\r$//g\n,w'   # delete a carriage return at line end

odcfile "$testfile"



printf "\n" | od -A n -c
printf "\012" | od -A n -c
printf "\x0a" | od -A n -c

printf '[ctrl-v][ctrl-j]' | od -A n -c      #  \n or ^J


printf "\r" | od -A n -c
printf "\015" | od -A n -c
printf "\x0d" | od -A n -c

printf '[ctrl-v][ctrl-j]' | od -A n -c      #  \r or ^M


# vim
createfiles

vim "$testfile"
#...
:set number
:set list
:%s/^M//g
:set fileformat=unix
#:set fileformat=dos
:x

odcfile "$testfile"


# edit files in-place with vim

createfiles

# delete newlines in-place
vim -e -s +':%j' +'w!' +'qa!' "$testfile"
odcfile "$output"

createfiles

# replace every \r with \n
# cf. http://vim.wikia.com/wiki/Change_end-of-line_format_for_dos-mac-unix
vim -e -s +':%s/\r/\r/g' +':set fileformat=unix' +'w!' +'qa!' "$testfile"
odcfile "$output"

createfiles

# delete every \r
vim -e -s +':%s/\r//g' +':set fileformat=unix' +'w!' +'qa!' "$testfile"
odcfile "$output"

createfiles

# delete \r only when it occurs at the end of a line
vim -e -s +':%s/\r$//g' +':set fileformat=unix' +'w!' +'qa!' "$testfile"
odcfile "$output"

createfiles

# replace carriage return line endings with \n
# cf. Getting rid of ^M - mixing dos and unix, http://www.vim.org/tips/tip.php?tip_id=26
printf "\r" >> "$testfile"
vim -e -s +':g/\r$/s///g' +':set fileformat=unix' +'w!' +'qa!' "$testfile"
odcfile "$testfile"

createfiles

# delete last \n of file
vim -e -s +':set noeol bin' +':set fileformat=unix' +'w!' +'qa!' "$testfile"
odcfile "$output"

createfiles

# change mixed mode files to DOS mode
#vim -e -s +':%s/\r\r/\r/g' +'w!' +'qa!' "$testfile"
sed -i '' -e s/$'\r\r'/$'\r'/g  "$testfile"
vim -e -s +':e ++ff=dos' +'w!' +'qa!' "$testfile"
vim -e -s +':e ++ff=dos' +':set ff=dos' +'w!' +'qa!' "$testfile"
odcfile "$output"

vim "$testfile"
:set ff?
:x

Deleting a line from a file matching criteria

I was messing around trying to figure out an easier way to remove entries from my /etc/portage/package.keywords file without having to drop into VI all the time and came up with this. You can put this into a bash script to make things alot easier on yourself if you are constantly altering your mask/use/keywords files in Gentoo.

sed -i '/x11-wm\/compiz/d' /etc/portage/package.keywords


The above example will remove any line that matches the regular expression x11-wm/compiz and edit the file in place "-i".

bash shell code to replace text in multiple files, multiple dirs, (but not in SVN dirs)

find . -name          *.php -exec sed -i 's/oldtext/newtext/g' {} \;
find . -name .svn -prune -o -exec sed -i 's/oldtext/newtext/g' {} \;


My understanding:

find files starting with . (local directory)

-name .svn -prune means if you find .svn for a filename (directory name), skip it.

-o OR

-exec execute

sed -i sed is the stream editor. -i means change the files in place.

's/new/old/g' Substitute old text for new text Globally.

{} sends the filenames that find found to sed

\; terminates the -exec from find, and \ escapes it so the shell won't think it means to end its command.


Mass find-replace using sed

Replace some widespread nasty hardcoded strings. 'sed $file > $file' doesn't work so hot so we use a temp file, and also make a backup of the old file.

for i in $(find . -type f); do sed 's/oldstring/newstring/g' $i > $i-tmp; mv $i $i-backup; mv $i-tmp $i; done