In an edX course on Unix tools I am running these weeks, I got asked for ideas on how shell scripts can be useful. This is a very interesting question, because the course focuses mainly on performing one-off tasks in the areas of software development, data engineering, and system administration, rather than automation through shell scripts. Here’s how I’m using shell scripting to enhance my personal productivity. I’ll post further installments regarding software development and system administration.
I have a $HOME/bin
directory where I keep my personal executable files. I maintain and distribute this on hosts I’m using via Git. The directory contains scripts such as the following. (Where the scripts are relatively small, somewhat portable, and of general interest I also show their contents.) Note that some of the operations are CygWin-specific and that many scripts can be enhanced to be made more robust for use in a production environment.
Make a beep sound; I run it to get notified when a long process has finished; e.g. make ; beep
or wait ; beep
.
!#/bin/sh
printf '\a'`
Fetch BibTeX entries from my global BibTeX files matching the specified search term.
Extract the key names of BibTeX entries as tags that my editor (vim) can use to jump directly to the entry from its citation.
#!/bin/bash
awk '/^@/{ printf "%s\t%s\t?^%s?\n", $2, FILENAME, $0}' FS=$'[,{ \t(]*' "$@" |
LC_COLLATE=C sort >tags
Run awk with the specified program argument on a CSV (comma separated values file); e.g. csvawk '{print $2 - $3}' list.csv
.
#!/bin/sh
prog="$1"
shift
awk 'BEGIN {FPAT = "([^,]+)|(\"[^\"]+\")"}'"$prog" "$@"
Add decimal separators to long numbers; e.g. ls -l | decimal
. (I know about ls -h
; I use this mainly when preparing tables with numbers for publication.)
#!/bin/sed -Ef
:a
# Add a , after a digit followed by three digits followed by non-digit or EOL
s/([0-9])([0-9]{3})([^0-9]|$)/\1,\2\3/
# Try the replacement again if the replacement succeeded
ta
Fix text with long lines by starting each sentence in a new line (as I advocate in my advice for writing LaTex documents), folding the rest, and removing carriage returns.
#!/bin/sh
# Remove carriage returns (keeping line feeds)
tr -d \\r |
# Start sentences on a new line
sed 's/\. */.\n/g' |
# Fold (but don't join) remaining long lines
fmt -s
Open the GitHub page associated with the repository in the current directory. The cygstart command is CygWin-specific, but there are similar commands in all GUI environments: kde-open, gnome-open, open (macOS).
#!/bin/sh
cygstart $(git remote -v | sed 's|:|/|;s|.*git@|https://|;s/\.git .*//')
Install my personal environment from its Git repo when I first setup a new host. It includes configuration for Bash, my editor (vim), the personal files, and so on.
Convert Google Earth KML paths into GPX for uploading them to Strava.
Create an iCalendar file for a specified event.
View a nicely formatted version of a Markdown document in my web browser.
#!/bin/sh
# View a markdown file
TEMPFILE=c:/tmp/md-$$.html
if ! [ "$1" ] ; then
echo "Usage: $0 file.md" 1>&2
exit 1
fi
pandoc --metadata pagetitle="$(basename $1)" --css=file:///C:/dds/home/lib/pandoc.css -s "$1" -o $TEMPFILE
cygstart $TEMPFILE
sleep 1
rm -f $TEMPFILE
Extract an abstract from a LaTeX document in text form, suitable for pasting it in a paper submission form.
#!/bin/sed -nf
/\\begin{abstract}/,/\\end{abstract}/ {
/{abstract}/d
s/\\textit{//
s/}//
s/\\,/,/g
/^%.*/d
s/\([^\\]\)%.*/\1/;
s/\\%/%/g
s/\\\\//
p
}
Add my digital signature to the specified PDF document.
Display a person’s phone numbers given their name. It obtains the phone number from the latest backup copy of my cell phone’s contact list.
Convert ancient RCS repositories into Git ones.
Show my recent Git commit activity; I use it to summarize what I’ve been working on in update meetings.
#!/bin/sh
find /home/dds/ -type d -name .git |
while read d ; do
git --git-dir=$d log --author=dds@aueb.gr --oneline --since='two weeks' |
sed "s|^|$d: |;s/\/\.git://;s/^.*\/\([^/]*\):/\1:/"
done |
awk '{print $1}' |
sort |
uniq -c |
sort -rn |
head -30
(Revisionist vim.) Edit the specified files, maintaining their timestamp.
#!/bin/sh
for i in "$@"; do
FILE="$i"
MTIME=$(stat -c %Y "$FILE")
vim "$FILE"
touch -d @$MTIME "$FILE"
done
Setup a remote host for logging in via ssh. I maintain a hierarchy of ssh keys based on how much I trust the physical and administrative security of a remote host. This script sets up the appropriate keys.
Set up the title of the terminal window I’m using to my login name, host name, name of the Git directory (if available), and the current directory.
#!/bin/bash
HOSTNAME=$(hostname -s)
if [ "$HOSTNAME" = "macpro" ] ; then
HOSTNAME=''
else
HOSTNAME="$HOSTNAME:"
fi
# Set the terminal title to the specified argument
set_title()
{
printf "\033]0;%s%s\007" "$HOSTNAME" "$1"
}
# Current directory is a Git directory
if [ -d .git ] ; then
set_title "${PWD##*/}"
exit 0
fi
# Loop to top until a Git directory is found
CURRENT_DIR=${PWD##*/}
while : ; do
cd ..
if [ -d .git ] ; then
set_title "${PWD##*/}...$CURRENT_DIR"
exit 0
fi
# Root directory?
if [ . -ef .. ] ; then
set_title "$CURRENT_DIR"
break
fi
done
Change the current directory to that specified by a Windows shortcut Uses the Outwit readwinlink command.
#!/bin/sh
cd $(cygpath $(readwinlink $1 | tr -d \\r))
Update my web home pages from their locally-maintained content.
Print the specified (or current) time in other time zones and the converse. I demonstrate this in the course.
Comments Toot! TweetLast modified: Monday, March 23, 2020 11:43 am
Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.