Script to pump output into a text file and open it in an editor
I use this little script a lot when I am running some command in bash (on Cygwin in Windows) and I want to capture the output into a text file for display into my favourite editor (like UltreEdit).
For example, the tree command (or a recursive ls) will have a lot of output if you run it on a directory with a few children and a few levels of nested folders. Because the output is usually too large to view nicely in a single screen of text on a console, I will want to view it in a text editor where I can manipulate it: search through it, cut/copy/paste contents and generally modify it.
Before I wrote the script this post is about, I would do this in the following way:
tree > /tmp/temp.txt; u /tmp/temp.txt
Easy enough, but tiresome to type over and over.
In the above snippet, the u command refers to one of my most used custom scripts to open a text file in my favourite editor (with a few bells and whistles). It could be replaced with the following in this case:
tree > /tmp/temp.txt; Uedit32.exe `cygpath -w -a "/tmp/temp.txt"` &
Or more simply, a *nix tool like vim or less (though less won't let you edit it).
tree > /tmp/temp.txt; vim /tmp/temp.txt tree > /tmp/temp.txt; less /tmp/temp.txt
Now, I will do this:
tree | intoTempFile
The intoTempFile script will write the output into a timestamped temp file (C:\cygwin\tmp\temp_20141016_220342.txt) and open it in UltraEdit for me. Here is the script.
#!/bin/bash
# ------------------------------------------------------------------------------
# -- Into Temp File.
# ------------------------------------------------------------------------------
# Redirect piped input into a temp file and open it in UltraEdit.
# Usage: someCommand | intoTempFile.sh [altFilename.txt] [-t]
# ------------------------------------------------------------------------------
# -- Variables for this script.
# ------------------------------------------------------------------------------
# Shortcut for the name of this file - for docs.
commandName=`echo $0 | sed 's|.*/||'`
# Output file.
tempFile=/tmp/temp_$(date +"%Y%m%d_%H%M%S").txt
# To tee or not to tee?
shouldUseTee=no
# ------------------------------------------------------------------------------
# -- Common functions for this script.
# ------------------------------------------------------------------------------
# === FUNCTION ===============================================================
# DESCRIPTION: Usage message.
# PARAMETERS: -
# RETURNS: -
# ==============================================================================
function usage() {
echo "Usage: someCommand | $commandName [altFilename.txt] [-t]"
echo "-t means use tee. Without it, nothing is output to console."
}
# === FUNCTION ===============================================================
# DESCRIPTION: Process all arguments to script. How to handle getopts args
# and operands at the same time:
# http://stackoverflow.com/a/21169366/257233
# PARAMETERS: -
# RETURNS: -
# ==============================================================================
function processArguments() {
# Arg checks.. No more than two args
if [ $# -gt 2 ] ; then
echo "** Incorrect number of args specified **"
usage
exit 22
fi
# Loop to handle all parameters
non_option_parameters=()
while true; do
# Process single letter args.
while getopts "$OPTIONS" option; do
if ! processSingleLetterArguments "$option"; then exit 9; fi
done
if ((OPTIND > $#)); then break; fi
non_option_parameters+=(${!OPTIND})
# Handle operand arg - file name
if [ -z "$searchTerm" ] ; then
tempFile="${!OPTIND}"
fi
((OPTIND++))
done
# ---------------------------------------------------------------------------
# Post argument processing - logic that must be applied once we know all args.
# ---------------------------------------------------------------------------
}
# === FUNCTION ===============================================================
# DESCRIPTION: Process single letter args via getopts
# PARAMETERS: -
# RETURNS: -
# ==============================================================================
OPTIONS=":t"
function processSingleLetterArguments() {
case "$1" in
t ) shouldUseTee=yes;;
\?) usage "*** Invalid option to $commandName: -$OPTARG ***"; exit 10;;
:) usage "*** $commandName - option -$OPTARG requires an argument. ***"; exit 11;;
esac
}
# === FUNCTION ===============================================================
# DESCRIPTION: Output a single line
# Will query tee variable.
# PARAMETERS: 1 - line to output
# RETURNS: -
# ==============================================================================
function outputLine() {
if [ "$shouldUseTee" == "yes" ] ; then
echo "$1" 2>&1 | tee -a "${tempFile}"
else
echo "$1" >> "${tempFile}"
fi
}
# ------------------------------------------------------------------------------
# -- Script logic.
# ------------------------------------------------------------------------------
# Process command line arguments.
processArguments "$@"
# Preserve indenting of source.
IFS='
'
touch "${tempFile}"
outputLine "Starting output."
outputLine "----"
outputLine " "
while read -r x ; do
outputLine "$x"
done
u.sh $tempFile
By default this will not show the output to the console. I can change that with the -t option as below - which will use tee to duplicate the output to console as well as a file. I don't usually use this though because it makes the script a lot slower.
tree | intoTempFile -tAlso, if I want to control the path to the text file being used, I can specify it like so.
tree | intoTempFile /tmp/treeList.txt