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