Permalink
Browse files

initial checkin

  • Loading branch information...
jwcxz committed Nov 18, 2013
1 parent be1879a commit dfbd1634a65b946bc7a0a4336b167dfe80e0a528
Showing with 201 additions and 3 deletions.
  1. +17 −3 README.md
  2. +15 −0 example.cfg
  3. +169 −0 logcp
@@ -1,4 +1,18 @@
logcp
=====
logcp - Bulk Copy with Manual Interface
=======================================

Performs bulk copy operations allowing users to manually remap source objects to destinations
This script looks at some number of most-recently-modified files in a source
directory and copies them to a destination allowing the user to direct the
objects to manually-defined deestination directories as they pass through.

I find this useful for handling stuff like log files and backups.

Syntax: `logcp [num]` where `num` can optionally be how far back to go back in
the recent files to import. At this point, an editor will open up with the
opportunity to say where the folder will go according to the screenshot below.

Configure the variables in `example.cfg` first and save that file as
`~/.logcp.cfg`.


![screenshot](https://raw.github.com/jwcxz/vim-logcp/master/logcpmap.png)
@@ -0,0 +1,15 @@
# directory for source objects
SRCDIR=/mnt/logs-raw

# base destination directory
DSTDIR=/mnt/logs-organized

# file to log copy operations to
LOG=$HOME/.logcp.log

# number of most recently modified objects to process
NUM=25

# debug command to prepend to file operations (useful for dry-running the
# script)
#DRYRUN="echo -e \t"
169 logcp
@@ -0,0 +1,169 @@
#!/bin/bash

# logcp
# jwc :: jwcxz.com
# a small script to copy a series of files (either standalone or in
# directories) based on recent modification time to a new place

# colors
CRST=`tput sgr0`
CRED=`tput setaf 1`
CYLW=`tput setaf 3`
CGRN=`tput setaf 2`
CDBG=`tput setaf 4`

# look for config file
if [[ "$CFG" == "" ]]; then
CFG="$HOME/.logcp.cfg"
fi

if [[ ! -f "$CFG" ]]; then
echo $CRED"no config file found!"$CRST
exit 1
fi

# read in the config
. $CFG

# optionally override number of objects to look for
if [[ "$1" != "" ]]; then
NUM="$1"
fi

# ensure all vars are configured
if [[ "$SRCDIR" == "" || "$DSTDIR" == "" || "$LOG" == "" || "$NUM" == "" ]]; then
echo $CRED"configuration incomplete"$CRST
exit 1
fi

# mapping file
MAP=`mktemp /tmp/logcp-map-$USER-XXXXXXX.logcpmap`

# marker for lines that are destinations (prefix)
DESTPFXRE='^\s*->\s*'

# include files with . at the beginning
shopt -s dotglob


cp_cmd () {
origobj=`realpath "$SRCDIR/$1"`
destdir=`realpath "$DSTDIR/$2"`

# make sure destination doesn't already exist, give up otherwise
[ -e "$destdir" ] && return 10

# make destination directory
$DRYRUN mkdir -p "$destdir" || return 20

if [ -d "$origobj" ]; then
# source was a directory, so copy everything in it
$DRYRUN cp -a "$origobj/." "$destdir" || return 30
elif [ -f "$origobj" ]; then
# source was a file
$DRYRUN cp -a "$origobj" "$destdir" || return 31
else
# source doesn't exist
return 11
fi

# record new destination to history
echo "$dest" >> "$LOG" || return 40

return 0
}

cp_cmd_ret() {
case $1 in
0)
echo $CGRN"ok"$CRST
;;
10)
echo $CRED"failed: destination exists"$CRST
;;
11)
echo $CRED"failed: source doesn't exist"$CRST
;;
20)
echo $CRED"failed to make destination directory"$CRST
;;
30)
echo $CRED"failed to copy source directory"$CRST
;;
31)
echo $CRED"failed to copy source file"$CRST
;;
40)
echo $CRED"failed to write to logfile"$CRST
;;
esac
}


### MAIN LOOP ###

# read $NUM latest lines and build map file
ls -1tr "$SRCDIR" | tail -n "$NUM" | sed -e 's/$/\n -> .\//g' > "$MAP"


# invoke editor on mapping file, but while in the destination directory (to
# enable autocompletion)
cd "$DSTDIR"
$EDITOR "$MAP"
cd -


# interpret user input
orig=""
last=1
cat "$MAP" | while read mlineraw; do
# strip out comments and trailing whitespace
mline=`echo "$mlineraw" | sed -e 's/\s*\(#.*\)*$//g'`

if [[ "$mline" == "" ]]; then
# empty line
continue

elif [[ "$mline" =~ $DESTPFXRE ]]; then
# destination
last=1

# strip off destination prefix
dest=`echo "$mline" | sed -e "s/$DESTPFXRE//g"`

# don't try to copy if the origin isn't specified
[[ "$orig" == "" ]] && echo $CRED"ignored $dest"$CRST && continue

# if the destination was filled in, try to copy
if [[ "$dest" != "" && "$dest" != "./" ]]; then
# copy and print result
dbg=`cp_cmd "$orig" "$dest"`
ret=$?

echo -n " -> $dest : "
cp_cmd_ret $ret

# print debug output from the action
if [[ "$dbg" != "" ]]; then
echo $CDBG"$dbg"$CRST >&2
fi

else
echo $CYLW" XX ignoring"$CRST
fi

else
orig="$mline"

if [[ $last -eq 0 ]]; then
echo $CYLW" XX ignoring"$CRST
fi

echo "$orig"
last=0
fi
done


# get rid of map file
rm -f "$MAP"

0 comments on commit dfbd163

Please sign in to comment.