‎ > ‎


#     Name: $HOME/code/misccode/oneliners
#  Summary: Programming and sysadmin fragments I've collected over the 
#           years.
#  Created: Tue 02 Jun 1998 10:52:11 (Bob Heckel)
# Modified: Wed 10 Aug 2011 12:21:22 (Bob Heckel)

xxPERLxx START:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-: {{{1

$ find `perl -e 'print "@INC"'` -name '*.pm'  # which Perl modules are installed

$ find /usr/lib/perl5/site_perl/5.6.1/ -name '*.pm'  # which Perl modules I installed

$ perl -V  # determine the @INC path

# Test perl code (or a regex) interactively in the Perl debugger:
$ perl -de 0
DB<1> $x='a1'; $x=~/(\d)/; print $1 <---must be on same line or lose $1

# Test perl from the command line without debugger (hardcore):
$ perl; $x='test string'; $x =~ /^(test).*/; $y=$1; print $y; <Ctr-d>
# Better
$x='test string'; ($y = $x) =~ s/^(test).*/$1/; print $y;
# Best (we get readline capability)
perl -e '$x="test string"; ($y=$x)=~ s/^(test).*/$1/;print $y;'

# Simple test regex test from commandline without needing a variable:
perl -e 'print "found" if "a"=~/[^1-9]/'

# Hash slice:
perl -e '@h{"key1", "key2"} = (1,2); print $h{key2};'

# Regex to commify commafy a number (see ~/code/perl/

# De-chomp un-chomp reverse chomp:
for ( @lines ) { $_ .= "\n"; }

# Regex to pick out the filename, i.e. basename, tail, and strip the path off:
$basefilename = $1 if $fullyqualifiedpath =~ m|[/\\:]+([^/\\:]+)$|;
# Pick out the fully qualified path and strip off the filename:
$directory = $1 if $fullyqualifiedpath =~ m|(.*[/\\:])+[^/\\:]+$|;

# Specify where to install Perl module (if you want a non standard directory):
perl Makefile.PL PREFIX=~/perllib
# then must later say  use lib '~/perllib';  or  export PERLLIB=~/perllib

# Determine if singular or plural word is required:
printf("Retrieving %d email%s...\n", $mailcount, $mailcount==1 ? "" : "s");
my $r = $rchg!=1 ? 'records' : 'record';

# Determine current day of the week:
$current_weekday = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[localtime(6)];

# Canonical directory read:
opendir D, "$dir" or die "$!"; @FILES=grep { !/^..?$/ && !-d } map "$dir/$_", readdir D;
# Quick directory read, skip dot files while reading directory:
@files = grep(!/^..?$/, readdir DIR);

# Put a pair of items into a hash:
$header{$1} = $2  while /(File|Node|Prev|Next|Up):\s*([^,]*)/g;
# Better
%h = /^(.*?): (.*)$/gm;

# Carriage return newline (i.e. linefeed) cleanup.

# chomp improvement esp. Windows, remove <CR> and/or <LF> from the end of $_

# Cache keys in a hash (the Orcish maneuver), sort on modified time:
@sorted = sort { ($modtimes{$a} ||= -M $a) <=> ($modtimes{$b} ||= -M $b) } @filenames;

# Rewind a file handle
seek(FILEHANDLE, 0, 0);

# Cryptic OOP constructor:
sub new { bless({}, shift); }

# Do something every 5 times using modulus
unless ( $i++ % 5 ) { print 'foo'; }

# Do something every 3000 times using modulus
print $_ if ($i++ % 3000) == 0;
next unless ( $. % 3000 ) == 0;

# Find only unique array elements:
%seen = undef; @unique = grep(!$seen{$_}++, @thearr)
# Better
@unique = keys %{ { map {$_ => 1} @possibleduplicateslist } };

# Remove empty or undef elements from an array:
@x = grep { !/^$/ } @x;

# Remove part of string and 'chomp' all elements in an array in one swoop.
map{ s/.*=// && s/[\r\n]+$// } @previousrun;

# Format date string (see LibC for %b, etc.).  E.g. this rets 'May 25'
use POSIX qw(strftime);
$fmtdt = strftime("%b %d", localtime(991422942));
$matchdt = strftime('%Y%m%d%H%M%S', localtime(time));

# Time stamp the last modified date.
my $mtime = (stat($0))[9]; my $t = localtime $mtime; print "Last Modified $t";

# Want new string substitution without clobbering original variable:
($y = $x) =~ s/foo/bar/g;

# Default (unless a 0 is a valid possibility)
$leavealoneifset ||= $default;
# or 
$best_suffix ||= $soso_suffix || $notsogood_suffix || 'txt';

# Replacer (recursive with backup) replace all instances of XXX (see :args :argdo or ~/bin/replace)
$ find -name foo.txt | xargs perl -pi.bak -e 's/XXX/bobh/'

# Split a scalar into an array, saving only part of the split result.
$x = 'zero:one:two';
@z = (split /:/, $x)[0,2]    # @z contains 'zero', 'two'

# lvalue is in scalar context (right side is therefore evaluated in a scalar context, $a gets 8):
$a = (2, 4, 6, 8); 

# Prepend, concatenate, something to each element of array:
@x = grep { s/^/foosuffix/ } @x

# Input from args or stdin, smash several all parameter arguments into one:
$_ = (join ' ', @ARGV) || <>; 

# Source code passed in implicitly via standard input:
echo "print qq(Hello @ARGV)" | perl - World

exit 0  # <--- success  exit 1 <--- failure  both same as shell

# Determine which compiler Perl was compiled with
perl -e 'use Config; print "$Config{'cc'}"'

use whine qw(toobusy twokids codetooscarylookin);      <---no commas!

# Iterate over a loop
for ( $i=0; $i<@colors; $i++ ) { ... }
# or 
for ( $i=0; $i<=$#colors; $i++ ) { ... }

# Constant declaration:
use constant SECONDS_PER_DAY => 60 * 60 * 24;       # 86400
$delta = abs($stamp - $stamp_mirror) / SECONDS_PER_DAY;

# Constant used as filehandle (must use concatenation in the open()):
use constant OUTPUTTXTFILE => 'foo.txt';
open FILE, '>>'.OUTPUTTXTFILE || die "$0: can't open file: $!\n";

# Classes OOP
# same as
Request::redirect($request, $new_url)

# Thin out, print 10 random lines from a file (good for creating dummy files):
cat smallBEN.txt | perl -e '@line=<>; for(1..9){print $line[int rand @line]}'

# A subroutine's incoming parameters are held in @_  This includes flattened arrays, etc. (it may be inefficient since it is "pass by value").
E.g. my @parms = @_;

# Force, prepend, a non-standard directory onto @INC:
unshift(@INC, '.');
# More elegant prepending of @INC:
use lib ".";

# Don't be greedy on regex:
$x = 'multi, comma, line'
$x =~ /(.*,)/   <---greedily returns 'multi, comma,' in $1
# but replacing the dot with  [^,]  i.e. what you don't want is non-greedy
$x =~ /([^,]*,)/  <---returns 'multi,'

# Regex matches floating point numbers.
# or regex that matches floating point numbers less Perlishly,

# Remember not to use = when you need =~
$x =  /foo/;  # searches $_, puts result in $x
$x =~ /foo/;  # searches $x, discards result

# Strip HTML tags from a string:
$string =~ s/<([^>]|\n)*>//g;

# Lookahead (?=) lookbehind (?!) regex assertions.
$x = "foobar";
$x =~ /foo(?!bar)/;  # doesn't match, 'bar' follows 'foo'
$x =~ /foo(?!baz)/;  # matches, 'baz' doesn't follow 'foo'
$x =~ /(?<!\s)foo/;  # matches, there is no \s before 'foo'

# On the fly substitution of array scalars with hash references:
@usernames = ('joe', 'ted', 'larry');
map { $_ = {$_ => length} } @usernames;
# Now @usernames is ( {'joe' => 3}, {'ted' => 3}, {'larry' => 5})
print $usernames[0]->{joe};  # rets 3

# Redirect STDERR error messages to STDOUT.
open(STDERR, ">&" . STDOUT) or die "Cannot Redirect STDERR: $!";

# Low-level alternative to print
write(2, "I'm using STDERR", 16);

# Want affirmative from user:
die unless <STDIN> =~ /^y|^yes|^ok/i;
# or
<STDIN> ne "n\n" ? print "ok\n" : die "Exiting\n";
print "keep going? "; <STDIN> eq "y\n" ? print "ok\n" : die "dead\n";

# Skip the first line of a textfile:
cat junk.txt | perl -e 'while(<STDIN>){print $_ if $.>1}'       # ok
cat junk.txt | perl -ne 'print if $.>1'                         # best

# Lowercase a word from the command line:
$ echo ThisWord | perl -pe 's/(.*)/\L$1\E/'

# Uppercase (a.k.a rightcase titlecase smartcase) first letter of word in $all_lower:
($first_ltr_uppercased = $all_lower) =~ s/(\w+)/\u$1/g;

# Delete lines containing for each file in directory:
perl -pi.bak -e 's/.**//g' testch*.ht
# Change background color of all webpages, recursively:
find . -name '*.html' -exec perl -pi.bak -e "s/BGCOLOR=\"#ffffff\"/BGCOLOR=\"#cccccc\"/" {} \;
# Better
find . -name '*.html' |xargs perl -pi -e 's/BGCOLOR=\"#ffffff\"/BGCOLOR=\"#cccccc\"/'
# Delete multiple blocks paragraphs of text (consecutive with start and finish lines):  TODO why can't use xargs (it only mods first file)??
for f in `find . -name 'testch*.htm'`; do perl -i -e 'BEGIN{$/=undef}$x=<>;$x=~s/Ukrainian Banner Network 468x60 START.*?Ukrainian Banner Network 468x60 END/FOOZBALL/sg;END{print $x}' $f; done

# Swap array elements using an array slice:
@x = qw(a b c);
@x[0,1] = @x[1,0];  <---holds bac now

# In Perl, unlike shell and C:
@ARGV contains the command-line arguments for the script but does not include the command name.  E.g. $ ./ foo bar  <---$ARGV[0] is foo
# Get at them like this:
foreach $arg ( @ARGV ) { on param $arg one at a time... }
# or better:
map { print "$_\n" } @ARGV;
# Contrast with:
while ( <ARGV> ) { chomp; on each line of each param... }

# Filter out all but plain text files from the command line parameters.
@ARGV = grep { -f && -T } @ARGV;

# Clear, initialize, the hash.
%hash = ();  #     <---NOT  %hash = {};

# Parse a date string:
($day, $mon, $year, $yday) = (localtime())[3,4,5,7];

$ perl Makefile.PL && make && make test && make install  # perl install mantra.  build module downloaded from CPAN.

# Number of elements in hash:
print scalar keys %myhash;

# Perl variable heredoc
$stuff = <<"EOT";
# or Perl print heredoc
print <<"EOT";

# Variable interpolation of constants -- print (ugly but it works):
use constant FOO => 0;
print qq:The value of FOO is @{[ FOO ]}\n:;
# Variable interpolation of constants -- regex (ugly but it works):
use constant EXTENSION => 'PDF';
next unless ( $d =~ /.*@{[EXTENSION]}$/ );

# Search file for lines (records) containing a specific 2 digit number in a
# specific column position, in this case 77 and 78.  Like a database query.
$ perl -ne '/.{76}(..)/; print if $1==15' foo.txt
# same as the verbose:
$ perl -ne '$_ =~ m/.{76}(..)/; print "$_" if $1 == 15' foo.txt
# or for character queries:
perl -ne 'm/.{174}(\w)/; print if $1 eq "Y"' foo.txt

# To sort on a specific column, see the Schwartzian transformation.

# Slurp an entire file into a single variable -- make sure ff=unix !!
my $str = do { local $/ = <FH> };  # slurp
# Can use __DATA__ filehandle like SAS' CARDS; or DATALINES;
{ local $/ = undef; $contents = <DATA>; }

# Current time timestamp since the Epoch:
print localtime();
# Current time timestamp human-readable:
print scalar localtime();

# Current date today:
$currentday   = (localtime())[3];
$currentmonth = qw(January February March April May June July August September October November December)[(localtime())[4]];
$currentyear  = (localtime())[5]+1900;

# Create a unique filename based on seconds since the Epoch using Perl:
print "foo" . time() . ".txt";

# Remove quotes from each element of an array of enquoted items:
my @fl = map /'(.*)'/, @filelist;

# Create a hash using map on the fly:
my %h = map /(BF19\.\w\wX(.*)\..*)/i, @fl;

# Add the first and last columns (@F comes from using -a):
perl -lane 'print $F[0] + $F[-1]' whitespace_separated_nums.txt
# Thanks to the switches, this is what it's doing:
while ( <> ) { @F = split(' '); print $F[0] + $F[-1]; } 
# Compare with
cat whitespace_separated_nums.txt | awk '{i = NF; print $1 + $i}'

# Replace all occurences of number 55 with a random number less than 100 (TODO how to avoid .bak files?)
perl -i.bak -pe "s/55/int rand(100)/eg"
# Recursively for specific extensions
perl -pi.bak -e "s/Output Compiled Data/Output_Compiled_Data/" `find . -name '*.sas'`

# Simple way to comment out a block of code.
=debugbobh  ...code...  =cut

# Read user's input from the commandline:
chomp(my $transtyp = <STDIN>);

# Set a cookie (after Content-Type: line):
print "Set-Cookie: lastused=foo; path=/; expires=$cookie_expire;\n\n";

# Set a default for an undefined value (using the ternary hook operator):
$x = ($x ? $x : 42);
# Maximum using ternary hook:
$max = $x > $y ? $x : $y;

# Left zero pad a number:
$j = sprintf("%02d", $i);

# C's break is Perl's last.  C's continue is Perl's next.

# Read or edit a Perl module:
vi `perldoc -l net::ftp`

# Syntax check a directory:
for f in *.pl; do perl -c $f; done

# Switch -n says not to autoprint -p says to print while looping foo.txt -a gives @F

# Are columns 1 and 3 equal?
perl -ne '@x=split; print if $x[0] != $x[2]' foo.txt

# nl(1) number line replacement
perl -n -e 'print "$. $_"' foo.txt
# Better nl(1) number line replacement
perl -pe '$_ = "$. $_"' foo.txt
# Best nl(1) number line replacement
perl -pe 's/^/$.: /' file1 file2 file3

# Automatic LINE: label is available under -ne
perl -ne 'next LINE unless /eplicant/; print "$. $_"' bladerun_crawl 
# Simpler if don't need the label to break out of a nested loop:
perl -ne 'next unless /eplicant/; print "$. $_"' bladerun_crawl 

# Search a tab-delimited file
perl -ne '@x=split /\t/; print "@x" if $x[1]=~/foundme/' foo.txt

# Search a tab-delimited file after removing header line
perl -ne '@x=split /\t/; print "$x[0] and $x[1]\n" if $.>1' *.xls |sort|uniq

# Automatic command line Perl module installation:
perl -MCPAN -e shell  # interactive mode
perl -MCPAN -e 'install DBI'
perl -MCPAN -e 'install DBD::mysql'

# Print a random number (automatically seeded by Perl):
perl -e 'print rand()'        <---floating point from 0 to 1
perl -e 'print rand'          <---same
perl -e 'print int rand 5'    <---integer from 0 to 5
perl -e 'print int(rand(51)) + 25;'  <---integer from 25 to 75
# Print 3 random numbers which will be 1, 2, 3 or 4
for i in 1 2 3; do perl -e 'print int(rand(4)) + 1, "\n"'; done

# Remove nulls (ASCII 0) from a file (also works as :'<,'>!perl -pe 's/\0//g')
perl -pe 's/\0//g' 
# Remove single quotes from a file.  Simple substitution on the fly printing
# changes to STDOUT
perl -pe "s/'//g" junk

# Substitute, inplace edit, and make backup from command line.  NOT recursive.
# TODO why is -p mandatory, and the -e must stand alone
perl -pi.bak -e "s/old/new/g" *.pl
# or
perl -pi.bak -e  's/old/new/g' `find . -name "foo.txt"`

# Replace all instances in files without backups:
perl -pi -e "s:#\!/usr/bin/perl:#\!/usr/pkg/bin/perl:" junk
perl -pi -e "s/REPLACEME/foo/" dhammapada.rss

# Swap colon delimited items, looping over foo.txt
perl -pe 's/(.*):(.*)/$2:$1/' foo.txt

# Print capitalized words by looping over file and printing at end of file.
perl -ne 'push @w,/(\b[A-Z]\S*?\b)/g;END{print "@w"}' file.txt

# Parse a file for email address pattern (used for Palm Pilot Memo) by looping
# over file:
perl -ne 'print "|$1 $2" if /\w+ \w+ (.*)<(.*)>.*/' ~/.email_addr

# Uppercase all letters in file (works on foreign characters) to STDOUT:
perl -pe 's/(\w+)/\U$1/g' foo.txt
# Lowercase all words in a file to STDOUT:
perl -pe 's/(.*)/\L$1\E/' foo.txt
# In-place edit to lowercase all words:
perl -pi -e 's/(\w+)/\L$1/g' desc.LST

# Current time in seconds since the epoch
perl -e 'print time, "\n"'
# Convert a Unix time (1970 is epoch) to RFC822 format.
perl -e "print scalar localtime(983595600)"

perl -e "print crypt('mummy','garbagesalt'),\"\n\""

# Test system function outside of code to debug (Windows examples):
perl -e 'system "attrib +R c:/temp/translate.tpg"'
perl -e "system 'mozilla file:///C:/cygwin/tmp/junk.html'"

# Extract the rightmost (last) column.  Split on whitespace.  Don't need to
# know how many columns exist.  @F is automatic.
perl -ane 'print pop(@F), "\n";' foo.txt

# Extract the leftmost (first) column.  Split on whitespace.
perl -ane 'print shift(@F), "\n";' foo.txt

# Convert decimal to binary:
perl -e "print unpack('B32', pack('N', 12))"
# Convert binary to decimal:
perl -e "print unpack('N', pack('B32', substr('0'x32 . 1100, -32)))"

# Test a multi-line string using a regex:
perl -e 'print "match!" if "This is my\nmultiline string" =~ /This.*string/s;'

# Parse on specific fixed column positions -- also see
perl -ne 'push @x, unpack "@1 A36 @37 A36",$_; END{$i=1;for(@x){print "$_\t"; if(++$i%2){print "\n"' foo.txt

perl -e 'BEGIN{$foo="avenue"};print "ok" if $foo=~/ave/'
# Same
perl -e '$foo="avenue";print "ok" if $foo=~/ave/'

# Extract a section of a file where you know the start and end patterns.
awk '/first word/, /last word/ {print}' startendpatt.txt
# Same (don't need  while(<>){...}  when using -ne)
perl -ne 'print if /first word/ .. /last word/' startendpatt.txt

# Extract a section of a file where you know the start and end line numbers.
perl -ne 'print if 15 .. 17' foo.txt                     # inefficient
perl -ne 'print if $. >= 15; exit if $. >= 17;' foo.txt  # better

# Print repeat string 5 times:
perl -e 'while($i++<5){print "ok "}'

# Convert ASCII num to char:
perl -e 'print pack "C", 97'
# Convert ASCII char to num:
perl -e 'print unpack "C", a'

# Count the exact number of occurrences of X:
perl -e '$s="ThisXlineXhasXsomeXxsXinXit"; $x=($s =~ tr/X//);print $x;'

# Print 0123456789
perl -e 'print pack( "H2"x10, map { "3$_" } ( 0..9 ) )'

# Replacement for list ls -l 
perl -e 'print scalar localtime((stat "")[9])'

# Pipe delimit a space delimited file (to STDOUT):
perl -ne 's/ /|/g; print' foo.txt

# Get info about a module using -M
perl -MCPAN -e 'print $CPAN::VERSION'
perl -MMail::Sendmail -e 'print $Mail::Sendmail::VERSION'

# Show days between modify and access for all files in dir:
perl -e 'map \{printf "%10.3f - $_\n",(-C)-(-A)},@ARGV' *

# wc replacement:
perl -ne '@w=split; $x+=@w; END{print $x}' foo.txt

# Use capturing parentheses to swap two items:
grep -v fips | perl -pe 's/(.*) (.*)/\2 \1/'

# Is this module installed on this machine?  Does this module exist?
perl -MImage::ExifTool -e "print 'ok'"

perl -e 'print "it is now @{[scalar localtime]}"'
perl -e 'print "it is now ", scalar localtime'
# m/d/yyyy formatted date
perl -e '($d,$m,$y) = (localtime)[3,4,5];print join "/", $m+1, $d, $y+1900'

# Super ls list.  Don't display any file containing dontlistme in it.
ls | perl -e 'while(<STDIN>){print $_ if grep(!/dontlistme/,$_)}'
# Better
ls | perl -ne 'print if grep !/dontlistme/,$_'
ls listened/ | perl -ne 'print "$1\n" if /.*(2001_\d+).*/'
# Compare but do so less precisely since \d doesn't exist under awk
ls listened/ | awk '/2001_\w/{print $1}'

# Parse string into an array:
perl -e '@words = "What did he say?" =~ /([A-Za-z]+)/g; END{print "@words"}'

# Find user's home directory:
perl -e '$x=(getpwuid($<))[7];print $x'

# Do something alternating days, will return '1' every other day.
date | awk '{print $3}' | perl -e '$x = (<> % 2); END {print $x}'

# Does a file exist?  Pop message box if so
perl -e 'system msgbox if (-f "./myfile.txt")'
perl -e 'print "ok" if (-e "./bladerun_crawl")'

print "Maximum commandline index: $#ARGV\n";
print "Last commandline argument: $ARGV[$#ARGV]\n";

# Use a default if not provided on command line:
$ARGV[0] ||= 66;
$ARGV[0] = ($ARGV[0] ? $ARGV[0] : 66);  <---instead of this mess

# Insert an array inside roughly the middle of another array:
splice @arrayA, $#arrayA/2, 0, @arrayB;

# Create a module template (we only care about unless CPANing it)
$ h2xs -AX Foo::MyModule

# 'our' allows you to circumvent strict for variables you want accessible from anywhere using the $Package::variable or @MyModule::ISA notation.

# Delete specific hash keys:

# Pipes (can avoid using system()):
open OUT, "|more" or *OUT = *STDOUT;
open IN, "ps|" or die "Can't start ps";

@x = split /:/,  "ab:cd:::ef:gh";  <--- two empty fields between cd and ef
@y = split /:+/, "ab:cd:::ef:gh";  <--- one big fat delimiter between cd and ef

# Find all installation directories:
perl '-V:install.*'

# Using rcs (automatically inserts revision sequence on co)
our $VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/o);

# Quick install: cp ~/code/perl/ /usr/lib/perl5/5.8/cygwin/File (or
# other dir on the @INC path)
perl -MFile::Irenamer -e 'InteractiveRename(verbose,recurse)'

# Reverse sort a hash:
@files = sort { $filehash{$b} <=> $filehash{$a} } keys %filehash;

# Determine a script's module dependencies (add to eof):
END { print join( $/, values %INC ), $/ }

# Social security ssn number regex:

# Poor man's tac(1) to reverse lines in a file:
perl -e 'print reverse <>' foo.txt

# Use reverse video for debugging (this doesn't require ctrl chars, just paste)
print "DEBUG> \e[7mUnexpected format of 'mystr':\e[m\n";

pdoc -f binmode  # function perldoc

# Random array element 0, 1, 2 or 3
print $paragraphs[int rand 3];

m/$foo/o  # compile interpolation pattern only once o regex switch:

system('/bin/bzip2', '-k', @zipme);
system('cp', '-i', $maxname, 'c:/cygwin/home/bheckel/tmp/foo');

# Like SAS' scan()
$x = (split / /, $x)[0];

# Reference to hash of anonymous arrays (note curly braces for ref, NOT parens)
$h = { one => [ 'a', 'b', 'c' ], two => [ 'd', 'e', 'f' ] }; 

use Data::Dumper; print Dumper $myref;
open FH, '>foo' or die "$0: $!"; use Data::Dumper; print FH Dumper @a;

# Read a file into a variable:
open PID, '/usr/local/apache/logs/' or die"; $pid = <PID>;  close PID;

# Read a file into an array (one element per line):
@data = <FH>;
# Print 2nd line in that file:
print "$data[1]";

# push and pop == a stack
# push and shift == a queue

push @existingarray, 'more', 'stuff';

@array = ("anicca", "dukkha", "anatta");
%hash = (1=>'One', '2'=>'Two', '3'=>'Three');

$#array is the index of the highest defined array element
# Truncate an array
@whatever = ();  or  $#whatever = -1;

# Check webserver return code to see if it's down
perl -MLWP::UserAgent -e '$u=new LWP::UserAgent;$r=$u->head;print $r->{_rc}'

print "Content-type: text/html\n\n";  # web CGI (HTTP/1.0 at least)

# Split on pipes, print field of interest:
perl -ane '@x=split /\|/;print $x[0], "\n";' vcc.txt

# Split comma-delimited string into anonymous array and show 2nd element:
$a='one,two,three'; $aa = [ split /\s*,\s*/, $a ]; print $$aa[1];

# Unbuffer, i.e. make hot, the LOG filehandle (and switch back to the original):
select((select(LOG), $|=1)[0]);

# Is timestamp recent?:
perl -e 'print "ok" if (stat("prellg"))[9] > time-86400'

# Modify CPAN module settings (perl -MCPAN -e shell) TODO 2008-08-06 not working
cpan> o conf http_proxy
cpan> o conf urllist push ftp://myurl/'

while ( ($key, $value) = each %myhash ) { ... 

# Is module installed properly?:
perl -MDBI -e 0

# Append 2 hashes (leftside hash takes precedence):
%comb = (%hashx, %hashy);

die 'debug', scalar localtime;

# Canonical system call
system('mv', '-i', "$new", "$path/");

print 'deleted' if unlink '/cygdrive/x/sql_loader/junk';

my ($multiple, $vars, $must, $be, $parethesized);

# Canonical hash:
%hash = ("laurel" => "hardy", "nick" =>  "nora");
# Canonical array:
@array = (10, 20);

# Toggle warnings:
no warnings; $discSize=$W2LIni->{Recording}{mediaSize}; $mediaType=$W2LIni->{Recording}{mediaType}; use warnings;

# Canonical date
($mon, $day, $year) = (localtime())[4,3,5];

# Call sub 100 times, and time it
use Benchmark; timethis(100, "MySub()"); 

# Why anonymous arrays are useful:
@children = (\%john, \%peggy); $sues{'children'} = \@children;
# becomes simply
$sues{'children'} = [ \%john, \%peggy ];
print $sues{children}->[1]->{age};  # Peggy's age
# Same
print $sues{children}[1]{age};

# Quick dump Main (see for hash included version)
open F, '>junkdumpmain'; for $s(sort keys %main::) { local *sym=$main::{$s}; print F "\$$s is $$s\n" if defined $sym; print F "\@$s is @$s\n" if defined @sym;}
# Then do a >junkdumpmain to "seed" tail and...  TODO tail part not working
$ tail -f junkdumpmain | grep -a potentialHeaderFields junkdumpmain

$array[7][12]				# array of arrays
$array[7]{string}			# array of hashes
$hash{string}[7]			# hash of arrays
$hash{string}{'another string'}		# hash of hashes
$hohoh{Robot}{Santa}{Claus}='mostly harmful';  # hash of hash of hash

# Parse a textfile grid:
perl -ne 'push @AoA, [ split ];END{print "$AoA[1][1]\n"}' junk.txt

# Number of elements (minus 1 so say (0 .. $#a) ) in array:
perl -e '@a=(1,2,3);print $#a'

# Round a number:
printf("%.3f", 3.1415926535);

# Convert a hash to an array to make unique eliminate duplicates:
%hash = map { $_, 1 } @array; @unique = keys %hash;

# Canonical search and replace (interactive :bufdo %s/foo/bar/gic may be better):
$ perl -pi.bak -e "s/foo/bar/" *.sas

# Canonical perl translate
$novowels =~ tr/aeiou/!/;  # change any vowel in $novowels into !

($HOST = $host) =~ tr/a-z/A-Z/;  # uppercase en passant (but it's better to use \U and \L for Unicode)

# Sum the 3rd column of a file
perl -l -a -n -e '$n+=$F[2]; END{ print $n}' threecolumnsofnumbers.txt

Expressions - a sequence of literals, variables, function connected by one or more operators that evaluate to a single value-scalar or array. 
Statements are a complete unit of instruction for the computer to process. Statement modifiers: if, unless, until, and while.

# Canonical map:
my @tripled = map { $_ * 3 } @numbers;

# Canonical count number of elements in an array without a temp variable:
$count = () = myarray();

print 'hash key "c" is undefined and this will not autovivify it' if ! defined $h{c};

# Canonical print an array
@a = ('a','b','c'); print "Hello, $_" for @a;

# Canonical regex en-passant - EXTRACT first name (reads left to right)
my ($firstname) = $name =~ /($firstname_precompiledregex)/;
# Canonical regex en-passant - MODIFY first name (reads right to left)
(my $normalizedname = $name) =~ tr/A-Za-z//dc;

xxPERLxx END:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:

xxVIMxx START:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-: {{{1


" Delete specific line 10 and the 3 lines following it (total 4 lines deleted)
:10d 4

" Delete first replicant (only) from line 9 to end of file

" Delete line containing the *last* instance of string 'the_end' in a file:

" Substitute the word 'xx' for 'foo' if found in the line following one
" containing the word 'bar':

" Delete all spaces from the lines between, but not including, Section 1 and
" Section 2:
:/Section 1/+,/Section 2/-s: \+::gc
" Find Section 1, then first line with Subsection, step one line down (beginning of range) and find the next line with Section 2, step one line up (end of range):
:/Section 1/;/Subsection/+,/Section 2/-s: \+::g

" Add line before line starting with 'Section' is found.
:g/^Section/s//As you recall in&/
" Add line after line starting with 'Section' is found.
:g/^Section/s//&As you recall in/

" Delete all empty lines

" Thin out a file by deleting every other line
:g/^/ + d 
" or to delete 2/3 of the file:
:g/^/ +, ++ d 

" Doublespace a file:

" Delete all *lines* containing the word emacs.  E.g. 'Boot the emacs OS'

" Delete all lines NOT containing any part of these words.
" This use of the global command uses the OR operator \| (chaining alternation):

" Reuse a search pattern.  Single line yanked.
:/YankNextLine/+ y

" Yank all *lines* containing word into buffer A (must use uppercase register letter or only get last yank). Clear register A before beginning:
:g/Emily/y A
" Or move 'Emily' lines into a buffer for pasting somewhere else:
:,$g/Emily/d A

" Yank line above a blank line (e.g. last line in a block or paragraph) into
" register a.  Good for getting the latest from ~/bin/latebf19 output.
:g/^$/-1 y A

" Visualize, view, trailing spaces (assumes highlightsearch default is off).
:set hls<CR>/\s\+$<CR>

" Strip all trailing whitespace (especially useful in MVS SAS files):

" Surround each word with single quotes.  E.g. foo, bar, baz, boom:

" Substitute Ford to Decker where found on a line starting with the word Actor:

" Copy the line (or lines) *preceding* UNI to the last line in the file:
:g/UNI/- co $
" Go up 2 lines to do the copy:
:g/UNI/-- co $

" Find lines with 'Replicant'.  Then substitute 'were' with 'WERE NOT'.  Then
" copy those lines to the bottom of the file.  Pipe is a separator in vi.
:g/Replicant/s/were/WERE NOT/ | copy $

" Moves a section of text below another section of text.
:g/StartOfBlockToMove/,/NextBlockStartHere/-1 mo /MoveToAboveThisLine/-1

" Append all (potentially non-contiguous) lines containing 'eplicant' to
" junk.txt.  Do NOT forget the '.' (current line address).  junk.txt must
" exist.
:g/eplicant/ . w >> junk.txt
" or using marks:
:'a,'b g/eplicant/ . w >> junk.txt

" Specify which lines, starting with Th, should have their e turned to E.

" Reverse all lines in a file (the zero is a noop where the matching lines,
" i.e. all of them, are continually placed):

" Poor man's move (assumes UNI exists on lines 2 thru 4) UNI lines to EOF:
:g/UNI/ co $ | 2,4 d

" Write (append) individual lines to a file.  Don't forget the '.' 
" The dot address in front of the write command tells it to write only
" the line it is on
:g/eplicant/ . w >> junk

" HTMLify (htmlize htmlify).  TODO requires 2 passes.  Misses first line.
:g/^$/+ s/^./<P>&/
:g/^$/- s:.$:&</P>:

" Show match with context
:g/replicant/z#.5|echo "==========" 

" Confirm global :g actions:
:g/DELME/if input("line ".line(".").":".getline(".")) == "y"|delete|endif

" Delete a block range if you can determine start and end of blocks:
:g/^\s\+The SA/;/^ProdSp/ d

" Delete everything except these two strings:

" Make 2 copies of the entire file (%) and copy the copies to EOF.
" g/^/ means every line that has a start-of-line (which means every line).
:1,3 g/^/ % co $

" Insert specific lines of an external file at very top of your file.
:0r !head -n15 foo.txt

" Insert specific range of an external file at very top of your file.
:0r !awk'/start/,/end/{print}' foo.txt

" Sort in plain vi (w/o my '=' sort map):
At start of lines do ma, go to end of list, !'asort  <---go to EOL & no ':'!

" Delete everything prior to emacs, keep the rest of the line:

" Lowercase each letter in file (use u for uppercasing):
" Use L for lowercasing each line (use U for uppercasing):
" Lowercase or uppercase with \U all single line C-style comments:

" Lowercase a specific word (use \U for uppercasing):
" or better
" or shorter

" Move a non-blank line, 42, to the top of the file:
:42 g/./m0

" Find the first word peak appearing only AFTER the word am0908.  I.e. find
" AM0908 but don't stop, keep going, to find the first PEAK INFO after that.
/am0908/;/peak info

" Non-inclusive delete.  Only delete everything between these two lines:
:?superi? 1,/labor/ -1 d

" Insert a line, interleave, after each line in a file.

" Restrict the pattern search and line marking to a stretch beginning three lines past the last previous line that starts with the string 'Exercises' and ending at the end of the file.  +++ means previous 3 lines (ie up)
?^Exercises? +++ , $ g/foo/d

" Uppercase (a.k.a rightcase) first letter of specific word
" or uppercase (a.k.a rightcase) first letter of specific word if words are
" quoted
" foo becomes Foo
" Uppercase whole word
" foo becomes FOO
" Uppercase first letter of all words a.k.a titlecase.  Also see Perl solution.
:%s:[^ ]*:\L\u&:g
" or to smart-case (titlecase) all cap words as well

" Search and replace across lines (eg replace Acme Distributors with Barrett...
" First get instances not split over 2 lines---
:%s/Acme Distributors/Barrett and Sons/g
" Then get those split across newlines---
:g/Acme$/+ s/^Distributors/and Sons
:g/^and Sons/- s/Acme$/Barrett

" Fix Perl comment on current line to start with a capital letter and end with
" a period.
:s:# \(.\):# \U\1: | s:$:\.:

" Turn line containing only a url into an HREF
:0,$:s:\(.*\):<A HREF=\1>\1</A>:gc 

" Put angle brackets around an email address.  E.g. <>
" TODO fails on strings like
:0,$:s: \(\w\+@\w\+\.\w\+\)$: \<\1>:gc

" Write file to two different places (current dir and other) simultaneously:
:w | :w!/home/bheckel/tmp/%:t

" Quick date stamp on tail
:w u:/%:t.YdS   <---assumes my strftime vim map is available

" Insert date between stem and tail extension (still have to type the tail)

" Mainframe uses stem basename only ( goes as INCLUDE):
:!bfp % 'bqh0.pgm.lib(%:t:r)'

" Reorder a comma separated (CSV) file:
:%s/\([^,]*\),\([^,]*\),\([^,]*\),\(.*\)/\1,\3 \4,\2/
" Or slightly clearer:
:%s:\([^,]*\),\([^,]*\),\([^,]*\),\(.*\):\1,\3 \4,\2:
" Then remove the spaces:
s/[ \t]*,[ \t]*/,/g

" Change really, really, really or really, really, really, really... to very
:%s/\(really \)\(really \)*/very /

" Insert a literal null (ascii 0).  In insert mode:
Press Ctrl-v then 0

" If you know the column number which you want to act on:
" Replace columns 1 thru 70 with an X:
" or delete from current position to column 20
" if you're just viewing,  :vsplit  might be better

" Find parts of a word like re or retu or return:
" In code:
if wrd == "re" || wrd == "ret" || wrd == "retu" || wrd == "retur"                                
  "do something
" is now more cleanly represented as:
if match(wrd, "\\<re\\%[tur]\\>") > -1
  "do something

" Extended character set for foreign characters - show defined digraphs:

" Alternate foreign character digraph method (better if don't know the code):
:dig         <---determine digraph's decimal code on (right side)
Ctrl-v 174   <---in insertmode e.g. copyright � symbol is 169
To do unicode, must do this first:
set encoding=utf-8
:se digraph
Then in insertmode (e.g copyright symbol):
C<BS>o   <---Produces �
s<BS>s   <---Produces German � 

" Edit macro buffer:
qa    <---record macro
q     <---then you notice it's wrong, so stop
"ap   <---then edit what you've pasted
"ayy  <---yank the line back into buffer a
qa    <---try again

" Show where all tabs, EOLs, hidden chars, etc are on a whole a file:
:se list

" Scroll scrollbind windows together vertical default:
:se scb   <---each window
" Horizontal scrollbind
:se sbo=hor
:se scb   <---each window

" View this keyword anywhere in file (move cursor to word).  Think '[ is easier to reach on keyboard - lazy geek default show all'.

" Substitute, search and replace, on several files in a directory (e.g. instead of using ~/bin/replace)
" Recursively load the files (like :e *.c but that doesn't work)
:args **/*.c
:argdo %s:'\\\\rtpsawnv0312\\pucc:'C\:\\cygwin\\home\\bheckel\\projects\\datapost\\tmp:ge | update
" Bulk update substitute single quotes for double quotes in all open buffer files
:argdo g/libname/s/'/"/g | update
" Bulk update convert fully qualified path to SAS macrovariable in all open buffer files ( : and & make it even messier than usual)
:argdo %s:C\:\\cygwin\\home\\bheckel\\projects\\datapost\\tmp\\ADVAIR_HFA:\&DIRROOT:ge | update

" Simple bulk - must have used :args - e in ge keeps vim quiet if no match (c confirm doesn't appear to work-THERE IS NO CONFIRMATION), do a  :vimgrep /foo/ **/*.sas  first to verify what will change.
:argdo %s/foo/bar/ge | update

" Count words word count (returns e.g. '4 matches on 3 lines')

" DEPRECATED, use my .vimrc BuffersList() bbb cmap  instead to "bufgrep"
:bufdo %s/findme/&/gic

" Search and replace all buffers interactively
:bufdo %s/findme/changeme/gic

" Search find a word and move cursor offset to one or more char positions from match.
/myword/b     <---cursor is on m (the normal default -- beginning)
/myword/b+1   <---cursor is on y -- beginning
/myword/e     <---cursor is on d -- end (good for "delete thru this char": d /.../e )
/myword/e-2   <---cursor is on o -- end minus 2 chars
/myword/e+1   <---cursor is on char after myword -- end plus 1 char
/myword/e+    <---cursor is on char after myword -- end plus 1 char

" Insert date:

" Display color syntax:
:so $VIMRUNTIME/syntax/colortest.vim
" Display current syntax groups (best):
:so $VIMRUNTIME/syntax/hitest.vim

" Non-standard regex: \= in Vim is ? in normal regex-land.

" Write a specific range to a new textfile using marks a and b:
:'a,'b w newfile.txt

" Vim regex:
" If two or more
" Match the previous atom from 0 to m times
" Match the previous atom from 0 to m times but as little as possible i.e.
" non-greedy
" Match the previous atom n to m times but as little as possible i.e.
" non-greedy
" E.g. Non greedy search, match 3 to 5 a's but prefer the shortest match.
" Non-greedy Vim search (use :se hls to see the results better)
" E.g. string axbxb
/a.*b     <---greedy finds axbxb
/a.\{-}b  <---non-greedy finds axb
" Better pipe delimited non-greedy (e.g. "dod_yr|$1-4|REV|date of death" rets
" dod_yr).  Replace the first  .*  with  [^|]*  to be non-greedy

" Pad a row to a specific number of columns, 97 in this case, using a macro:
" Start on line of interest.
O#97i #0jYkR#"#jdd      <--- '^[' are escapes, there is a space after i
" It finishes on next line to process.
42@@      <---to do 42 more lines

Modeline samples.  Trailing ':' required for multiple set's.  /* vim: set tw=72 ft=sas ff=unix: */ # vim: set list syntax=off foldmarker=#{{{,#}}} foldmethod=marker tw=78:

" Substitute TBE2.FINAL.BF19.DATASET using nested capturing parens:
:0,$:s:BF19\.\(..\)\(.*\):FILENAME \12001 'BF19\.\1\2' DISP=SHR;:gc

" Substitute files for //IN JCL:
:0,$:s:\(.*\)://*IN      DD DSN=\1,DISP=SHR:gc

" Rename files interactively using vi:
:r !ls pattern*.txt
:%s/.*/mv & &/
:w !sh       <---run commands by writing them to the shell

" Create a unique filename based on seconds since the Epoch:
$ vi foo`date +%s`.txt

" Find two blank empty lines:

" Simultaneously turn flip change Yes to 1 and No to 0 in one swoop:

" Use calculator inside a Vim window:
:!echo 4+3+6 | bc

" Search for either string Yes or string No (alternation):
" Replace both strings Yes and No with foo:

" Encrypt file for first time: :X  then immediately :w (disable :set key=)

" Open file and place cursor at the search word ERROR or WARN:
vi -c '/^ERROR\|^WARN/' foo.txt

" Open a file while copying and pasting (yanking and putting) the first line
" at the same time.
vi -c ':y | put' foo.txt

Open Vim to last line of file, set textwidth:
vim -c 'set tw=68 et' +  foo.txt
gvim -c 'set lines=20 columns=150'
vi -c 'map q :q!<CR>' foo.txt
vi -c 'map q :q!<CR>' -c 'map z noop' foo.txt

" Add non-standard help files to Vim Help:
cd to the .txt
:helptags . 

" To read in fewer than all lines use the shell (hard to believe :1,9r doesn't
" work!)
:r !head -n30 foo.txt

" To print from GUI W32 Vim:

" Halve, cut in half the current file:
:%norm jdd

" Simple canonical increment without incpat.  Ctrl-v highlight from your start num then
:Inc  " or <C-A> if mapped --> vnoremap <C-A> :Inc<CR>

" Pattern replace '@' assumes IncPattern() in my .vimrc
"                pattern,start,increment
:,$call IncPattern('p@','s1','i1')

" Increment a left zero padded column of numbers (0000, 0100, 0200...), 
" highlight them then:
:'<,'>Inc(100)        <---Ctrl-a won't maintain the left zeros

" Increment a pattern (pattern should be '@'). Highlight area then :Incpat
" To override defaults: e.g. :1,4call IncPattern('pX','s0','i5')"  (p)attern, (s)tart, (i)ncrement by

" Folding by expression doesn't seem to work (2004-07-20).  Paste this Vim
" macro into a register to fold SAS macro blocks:
# Upload filename without extension tail (e.g if you're editing
:!bfp % 'bqh0.pgm.lib(%:t:r)'

" Yank the one single character that cursor is on

" Create fold zf, open fold zo, close all zx, delete zd, :set foldcolumn=2

" Open all folds zR (think 'release').  Close all folds zM (think 'mash').

" netrw plugin if vim already open (beware there is NO file locking here):
:Nwrite "daeb bheckel Tistyb4p tmp/testing/junk2z"
:Nread "mf bqh0 Tistyb4p pgm.trash(junk)"
:Nwrite "mf bqh0 Tistyb4p pgm.trash(junk)"
" Netrw using vim with ssh (similar using FTP):
$ vim scp://bheckel@
# or - note no colon and double slash
$ vi scp://rsh86800@rtpsh005//opt/QCServer/A.05.00/svr/files/Inspec_Lot-0108.log
" set bufhidden=hide to avoid reloading on every buffer reentry

" Debug shell script by doing an echo line below declaration:
:,$:s:\(export \(\w\+\).*\):\1
" Debug perl script:
:,$:s:\(my \(\S\+\).*\):\1

" Convert file to html (if code, it'll maintain syntax highlight coloring but
" must change header line to this <body bgcolor="#000000" text="#ffffff">):
:runtime! syntax/2html.vim

" nl(1) number line replacement
:g/^/exec "s/^/".strpart(line(".")."    ", 0, 4)

" If vim -d is not available resort to:  $ diff -ybB -W160

" Count delimiters quickly  :s/|//c  then undo

" Turn fscking tabs into spaces (depends upon tabstop value, usually set tabstop=2 for me)
" Find all leading tabs and replace with spaces.  Since every character in submatch(0) will be a tab we can replace each character with four spaces.
:%s/^\t*/\=substitute(submatch(0), ".", "    ", "g")
" Put the tabs back over the 4 spaces:
:%s/^ \+/\=substitute(submatch(0), "....", "\t", "g")

" Sort all non-blank lines from here down (alternative to visual mode & '=' ):

" Count bytes and words to cursor
g Ctrl-g

" Edit all .c files containing the word frame_counter
vim `grep -l frame_counter *.c`

" Search Vim help:
:echo $VIMRUNTIME   <---then  $ cd /usr/share/vim/vim63/doc  and grep
" Better (no quotes or slashes used here like vimgrep !), case insensitive, :cn to iterate results
:helpgrep holy-grail\c
:vim[grep] /holy-grail/ /usr/share/vim/vim70/doc/*

" Recursive vim search
:vimgrep /manufactur/ **/*.sas

" If you need to search but have several open files and don't want to shell out:
:vimgrep /select.*into/ *.plsql
:vimgrep /\CSELECT.*into/ *.plsql  " uppercase case sensitive search
" Then :cw or :cope to open results window
" Recursive search using star-star (slashes optional if not using a regex):
:vimgrep /select.*into/ **/*.plsql
" Picks up .vimrc's case sensitivity setting - override case-insensitive:
:vim Unexpected\C *.sas 
" Alternatively on systems with grep(1) - faster but won't recurse, use vimgrep:
:grep -i unexpected *.sas 

" Delete everything but the first 2 fields in a CSV

" Delete first 2 tab delimited fields (need ctr-v tab)
:%s/[^^I]*\{2}//gc  TODO does not work
" Alternative is to substitute the tabs for CR and do a :g!/^.../d

" Substitute a CR for each comma but don't be greedy doing the whole line by
" accident (basically replace the '.' in '.*' with '[^,]'):

" Canonical convert a file to HTML, opening the results in a new window:

" Crosshairs bullseye
:se cuc|se cul (or better :se cuc cul )

" To avoid forgetting to mkview before exiting
:map :w :w\|mkview

" View debug web page HTML/SAS Log output in Vim (using Vim instead of less)
w3m -dump 'http://rtpsawn321/sasweb/cgi-bin/broker.exe?_service=default&'|vim -R -c "se ft=saslog|map q :q<CR>" -

" Convert a comma delimited list to LIKE statements (TODO how to do IN('%ADVAIR%',...) ?
:,$:s:'\(\w\+\)[^,],:OR prod_nm LIKE '%\1%'^M:gc

" Find and edit an alias, executable, etc. wherever it is on disk:
$ vi `type -p prellg`

" Swap tab-delimited field 5 with 4 position (use :se list to view these tabs):
,$:s:^\([^	]*\)	\([^	]*\)	\([^	]*\)	\([^	]*\)	\([^	]*\)	\(.*\):\1	\2	\3	\5	\4	\6	:gc

" vim readonly
vi -R foo.txt

" Remove blocks, paragraphs of text from a series of files. Edit multiple files:
$ vim -c 'argdo /begin/+1,/end/-1g/^/d | update' *.c

" Slow and mostly useless sed replacement
$ vim -c 'argdo set nomore | g!/-2008/d | update' CI2003individualsRELEASE_Ven60.csv

" Compare vimdiff diff two existing buffers :vert diffsplit then switch to other buffer and :diffthis then force any changes :diffupdate when done reset the diff :se nodiff

" vimdiff keystrokes
do == :diffget  dp == :diffput

$ vim -u NONE -U NONE -N   <---no .vimrc and plugins ('clean' VIM)

Ctl-] and Ctl-t to navigate Vim Help links

" Insert timestamp at end of file
map ,d Go<CR><C-R>=strftime("%Y-%m-%d")<CR>

" Run vim commands from shell command line without opening file:
vim -c "s/hello/goodbye cruel/" -c "wq" fun.txt

" Matches any line meeting the constraints: 1) contains anything (.*) followed by ObjectName 2) starts (^) with something which isn't 'import' (\(import\)\@!)

" Determine length of longest maximum line (fn is custom in .vimrc):
:call MaxLineLen(1)

:DirDiff ~/projects/datapost/tmp/valtrex_caplets/CODE //rtpsawnv0312/pucc/valtrex_caplets/CODE/
:DirDiff . //rtpsawnv0312/pucc/VALTREX_Caplets/CODE/
" dp to 'diff put' change to the other window, arrow keys to nav (double arrow up to de-syntax)
To synch DirDiff: s  (in bottom pane with cursor ==>)
To synch DirDiff ranges of updates (internal DirDiff cmds like 'u' not working 2011-04-27):
:se nu

" Run info(1) on word under cursor. Good demo of running an arbitrary command on the current word.
map ;p :exe ":!info ".expand("<cword>")<CR>

" Convert a tab-stopped file to a space-formatted file:
:set expandtab

vi -S Session.vim
:map :w :mksession! \| :write<CR>

" Do not forget to save folds etc.
:au BufWinLeave * mkview

" Insert a sequential list of numbers similar to IncPattern()
:put =range(11,15)
" or
:for i in range(1,10) | put ='192.168.0.'.i | endfor

" Syntax highlight %THINGS% like that in a doc
syn match TODO "%\u\+%" containedIn=ALL

" Choose font.  Font tester: Illegal1 = O0
:set guifont=*
:se guifont=Andale_Mono:h9

Omnicomplete default key combination using syntax files in insert mode C-X C-O

Finds the next line longer than 80 characters:

Plugin Align comes as a vimball; vi Align.vba.gz :so %  install files correctly
:%Align ,  " parses whole CSV file into columns (can split on tab space comma etc.)
:'<,'>Align \t

" Turn all open buffers into tabs
:tab ball

" This foldmethod doesn't mod file
:se fdm=manual

" Virtual edit (ctrl-v extended)
:se ve=all

" Open in new tab
:tab h quickref

" Delete every line except lines starting with a 6:

" Modify every 6 except those in column 1 (do not use 'c' switch!)

" My bc function map
vnoremap <C-P> "ey:call CalcBC()<CR>

:args **/*.sas | args cfg/* | args **/*.map

vi -u NORC               <---skip .vimrc
vi -V2                   <---verify runtime startup etc
vi -S Session.vim        <---restore project folds, windows, etc.
K                        <---on (K)eyword for help or man etc.
:helpgrep foo bar\c      <---then :cw[indow] to navigate results
:h quickref              <---C-] and C-t  ctags fwd back navigation
:h function-list
:mes[sage]               <---show previous messages, errors, etc.
:echo loaded_matchit     <---1 if plugin is loaded (and 'let loaded_matchit=1' is in matchit.vim)
:scriptnames             <---or verify all plugins
:echo has('foo')         <---test existence of Vim variables
:echo &modifiable        <---boolean checking (scripts mainly)
:echo $VIMRUNTIME        <---determine Vim's location
:map z                   <---check if any z* keys are mapped
:so ~/.vimrc             <---reload me
:so $MYVIMRC             <---reload me
:let                     <---view all current Vim variable values
if &diff                 <---is diff running

" Chain two commands (TODO shortcircuits on 'Pattern not found'):
%s:<ExtractEnabled>0<\/ExtractEnabled>:<ExtractEnabled>1<\/ExtractEnabled>:g | :%s:<TrendEnabled>0<\/TrendEnabled>:<TrendEnabled>1<\/TrendEnabled>:g (zzapper)

" display with line numbers
:g/Line 8/#

" Maximum line length count:
:echo max(map(range(1, line('$')), "virtcol([v:val, '$'])")

xxVIMxx END:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:

xxUNIXxx START:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-: {{{1

# Canonical find and then grep
ssh rtpsh005 'find /opt/QCServer/A.05.00/svr/files -name 'Inspec_Lot-*' -mtime -3 -exec grep "Error:" {} \;'
ssh rtpsh005 'find /opt/QCServer/A.05.00/svr/files -name 'Inspec_Lot-*' -mtime -3 -exec grep "Error:" {} \; | tail'

# Find newish file that is not empty:
ssh rtpsh005 find /home/gaaadmin/GAAAdapter/gaa/logs -name 'InspectionRes*error*' -mtime -7 -a -size +0

# Specify user to login as:
ssh -l root

# grep but skip, ignore, the string 'foo' if in the same line:
grep findme * | grep -v foo

# Look in Julie chats for password related info (with context)
$ find . -name '*Bass*.txt' -print0 | xargs -0 grep -3 -i 'password'

# Send results of find to grep then send results of grep to pr then send
# results of pr to lpr.  The xargs command takes an argument and executes it.
find . -type f -print | xargs grep -l bobh | xargs pr | lpr

# Find the string 'bobh' in files in current & subdirs if the file is older
# than 365 days.
find -mtime +365 | xargs grep bobh

# Convert Macintosh to Unix file format: TODO how to do in-place change?
tr '\015' '\012' <file.mac >file.unix

# Poor man's copy cp:
cat <original.txt >duplicate.txt

# Remove or uninstall accidently untarred mess from a directory.  Tar undo.
# (Note: sometimes must gunzip first before untar; often must cd to / )
$ tar xvfj ~/w3m-0.5.2-2.tar.bz2  # original extraction
$ tar -tf ~/w3m-0.5.2-2.tar.bz2 | xargs rm -v  # reverse untar mistake

# Direct data to one file and errors to another:
(cat bladerun_crawl.txt nosuchfile.txt > bladerun_crawlcontents.txt) 2> errmsgonly.txt

# Put both STDOUT and STDERR in one file, send nothing to the console (error messages are written to STDOUT instead of STDERR)
ls goodfile.txt nosuchfile.txt > lsOutputWithAnyErrorMessages.txt 2>&1

# Keep a record of software installation:
./configure 2>&1 | tee log.configure
plnonstd | tee outputofplnon.txt
make 2>&1 | tee build.log
# To append further log to build.log, continue with:
make modules 2>&1 | tee -a build.log

# grep search for more than one pattern:
egrep 'foo bar|%JET' *

# Copy everything (except dot files) in a dir except for one file (smb.txt in this case):
cp /notathome/[^smb.txt]* /foodir

# Copy everything (including dotfiles & dot directories!) downward. /copiedtohere must exist first.
cp -R .* /copiedtohere
# Copy everything (including dotfiles & dot directories!) downward. /copiedtohere need not exists, it is created.
cp -R ~/copiedtohere .

# Don't show .c files
ls *[^c]
# Don't show files starting with a OR b
ls [^ab]*

# Compact move instead of the traditional  mv /usr/bin/blah /usr/bin/blah.bak 
mv /usr/bin/{blah,blah.bak} 
# Backup a file quickly:
cp myfilename{,.bak}

# Count how many directories (not including files, don't recurse):
\ls -ld * | grep "^d"| wc -l
# or
\ls -ld | awk '{if (/^d/) print $9}' | wc -l
# or print names of dirs
\ls -l | awk '{if (/^d/) print $9}'

# Count number of letters, etc. on the fly (-n skips automatic newline):
echo -n 'count me' | wc

# Count how many Vim Scripts use ``execute''?:
$ find /usr/local/share/vim -type f -name \*.vim -exec grep -l '\<exe\(c\(u\(te\?\)\?\)\?\)\?\>' {} \; | wc -l

# When your term displays a mess/garbage) after you cat or grep a binary file, reset it: 
echo CTRL-V ESC c 
# or (no dash!!)
stty sane
# Fix a bad ^H^H^H problem (that might have been caused by the above command)
set -o vi
stty erase ^H
# Turn off echoing of keystrokes (stty echo to turn back on)
stty -echo  

# List contents of file, breaking it up into one word per line. 
cat foo.txt | xargs -n1

# Keep checking on dead server with a shell do-loop or use my ruup - bash
while true; do ping -n 2 mainframe; date; sleep 600; done;
# or
while : ;do ping; sleep 600; done

# Infinite loop from the command line - ksh
while [ 1 ]; do date; sleep 10; done;
# or
while [ true ]; do date; sleep 10; done;

# Canonical Shell do loop.  Do something in a loop 3 times:
$ for i in 1 2 3; do echo 'bobh'; sleep $i; done

# Remote copy syntax example
rcp foo.txt zrtph128:/home/bheckel/tmp

# On the REMOTE Unix box:
$ /usr/X11R6/bin/xhost +daeb  # sometimes required to be run on LOCAL MACHINE
# On the LOCAL PC:
$ export DISPLAY=  <---sometimes leave off the last .0
$ /usr/dt/bin/netscape &
# or one-shot on LOCAL machine (assuming X-server is running on PC):
$ export DISPLAY= && mozilla&
# Test it:

# Cron
# min hr day mon wkday(0=Sun,6=Sat)

# Run cron job on last Sunday of every month (see also
18 * * * 0 [`date "+%d"` -gt 24] && /path/to/script

# Run cron job every 30 minutes:
5,35 * * * * /usr/bin/dfmon

# Run cron job every Saturday & Sunday at 3:59am 4:59am 5:59pm
59 3,4,17 * * 6-7 /bin/df -h 

# When a script is started from the cron and there is anything sent to STDOUT,
# it will either get logged in the system messages file or emailed to the root
# account.  To prevent this:
5 0 * * * /usr/bin/disk_hogs > /dev/null 2>&1

# Avoid email on cron output (use logfile instead):
59 * * * * /usr/bin/fooprg >> /home/bheckel/fooprglog.txt 2>&1

# Human readable disk space Solaris
df -h
# Human readable disk space HPUX
# Top CPU users HPUX (ugly but works)
UNIX95= ps -eo user,pid,pcpu,comm | sort -nrbk3 | head -10

# Poor man's cron bash.  Trigger at 4:00-4:59pm:
while true; do if [ `date +%H` -eq 16 ];then echo 'ok';fi; sleep 60; done
# Poor man's cron ksh.  Trigger at 4:00-4:59pm:
while [ 1 ]; do if [ `date +%H` -eq 16 ]; then date; fi; sleep 60; done;
# Poor man's cron.  Trigger at 8:11
while true; do if [ `date +%H` -eq 8 -a `date +%M` -eq 11 ];then echo 'ok';fi; sleep 60; done
# Poor man's cron.  Do NOT trigger the 4 o'clock run when I might be undocking
while true; do if [ `date +%M` -eq 20 -a `date +%H` -ne 16 ];then date;; fi; sleep 60; done
# Poor man's killer cron - closes rxvt when done
while true; do if [ `date +%H` -eq 16 ];then /bin/kill 1035;exit;fi; sleep 59; done

# Avoid Linux screensaver blanking
setterm -blank 0

# Determine IP address on Unix:
ping `hostname`
# or determine IP address on Unix:
grep `hostname` /etc/hosts | awk '{ print $1 }'
# or determine IP address on Unix:
ifconfig | grep "inet addr" |  grep -v "" | awk '{print $2;}' |  awk -F ':' '{print $2;}'

# Start (stop, restart) Samba on RedHat:
/etc/rc.d/init.d/smb start

# Restart Apache if can't find apachectl
kill -HUP `cat /apache/logs/`
# Restart Apache more gracefully
/usr/local/apache/bin/apachectl restart

# Send one program's STDIN to another's STDOUT using a pipe with no name.
$ mkfifo foo; cat foo
# In another xterm
$ cat > foo                   # and start typing
# or
# cat >/mnt/floppy/brewery    # and start typing

# Kill a user:
$ kill -9 `ps -aef | grep jondoe | awk '{print $2}'`

# Kill all LIMS users:
ps -es | grep lms_client_techops | while read pid do echo $pid kill -9 $pid done

# Instead of doing a ps -ef to know the pid and kill it manually every time:
$ kill `ps -ef | grep \`whoami\` | grep myProcess | grep -v grep | awk '{print $2}'` 

# Kill httpd:
kill -9 `ps | grep httpd | awk '{print $1}'`
for p in `pgrep httpd`; do kill -9 $p; done

# Kill several related processes at once:
ps | grep httpd | awk '{print $1}' | xargs kill -9

# If killall isn't working find pid:
for p in `pgrep smbd`; do kill -9 $p; done

# Kill fscking Norton antivirus
winkill `ps -W | grep rtvscan | head -n1 | awk '{print $1}'`

# Create a 100MB (100,000,000 bytes) dummy file of garbage (like mkfile) that
# is a specific size in bytes (~/code/perl/megfile alternative):
#                             ea block   num blocks
dd if=/dev/zero of=biggarbage bs=10000 count=10000

chmod: 4 read  2 write  1 execute  (for owner, group, world/all)

# For directories, the ``read'' permission is necessary to display a
# directory's contents, while the ``execute'' permission is sometimes called
# ``search'' permission and is necessary to actually enter the directory to
# use its contents. In a directory ``write'' permission on a directory permits
# adding, removing, and renaming files in that directory; if you only want to
# permit adding, set the sticky bit.
chmod +t pub/

# If a directory is set up with execute permissions only, everyone can go in
# the directory but only the owner of the directory and superuser can ls the
# files inside the directory.  Other users must know the name of the file they
# want (to edit, copy, etc.)
chmod 711 semiprivate/

# Set UID, setuid.  As root:
chmod +s fooanyonecanrun
# or (maybe better)
chmod 4755 fooanyonecanrun

# Enable all world to run command:
chmod a+x

# Use a remote file as a starting point without having to ftp/rcp first.
#             -------on oradev------  to Cygwin
rsh zrtph128 'cat /home/bheckel/junk' | vi -

# Canonical sort by largest files (descending), assumes filesize is in 5th column
ls -l | sort -r -n -k 5

# Top 20 largest files AND directories (Cygwin):
du -sk * | sort -rn | head -n20  # must use the '*' or get dir tot only
# Top 20 largest directories (NetBSD):
du | sort -rn | head -n20
# Top 20 largest directories
du -k| sort -rn | head -n20
# Total size of each item (file or directory) in CWD and sort numerically:
for i in *; do du -sk $i; done | sort -n

# HP-UX System Admin Tool -- sam
# Solaris Administration Tool -- admintool or sam
# Solaris top is prstat

# The first tar command creates (cf) an archive of thedir and places it into
# a buffer, instead of creating a file or writing it off to a tape. While the
# data is in the buffered area (-), it is sent to the remote host. When the
# data arrives at the remote host, the command changes to the directory /home
# and begins to extract ( xvfB) the contents of the archive from the buffer
# where it resides.  (B) is used for blocking and should be used to prevent
# data loss across the network.
tar cf - tar_me | rsh theotherserver '( cd /home/bheckel/todel; tar xvfB - )'

# Backup workbox code changes each weekday (where code/ is mounted, not symlinked)
(cd; touch .ts -d 'last monday 7am'; find code -type f -not -name '*.sw[op]' -daystart -newer .ts | xargs tar cvfz ${HOSTNAME}.tgz)
# Update code from emailed tgz on one of the homeboxes
(cd; tar --extract --verbose --gzip --keep-newer-files --file=ZEBWL10D43164.tgz)
# Backup homebox code since last "sync".  From any dropbox-aware box.
(cd; touch -d 'last friday 16:30' .ts && find -L code -type f -not -name '*.sw[op]' -newer .ts | xargs tar cvfz ${HOSTNAME}.tgz)
# Midweek backup homebox code (since last "sync").  From box the last untar occurred on.  ASSUMES tgz timestamp isn't from email save time.
(cd; find -L code -type f -not -name '*.sw[op]' -daystart -newer ZEBWL10D43164.tgz | xargs tar cvfz ${HOSTNAME}.tgz)

# passwd format
#    0        1          2          3        4      5       6
# Username:Password:Userid_Num:Groupid_Num:Gecos:Home_Dir:Shell

# Get basename and fully qualified path FQP from $1
$ basenm=`basename $1`
$ dirnm=`dirname $1`
$ echo "debug ${dirnm}${basenm}"
# or a replacement for 'basename'
the_var=foo.txt; echo ${the_var%.*}      <---returns foo

# Test availability of all hosts:
grep -v "#" /etc/hosts | awk '{print $1}' | xargs ping -c 1
# Contrast with (better if doing more than just a single command):
grep -v "#" /etc/hosts | awk '{print $1}' | while read EACHHOST do
  ping -c 1 $EACHHOST

# Keep alive keepalive after exit logout.  Execute it with the command "nohup", then log out.
nohup tar -cf /dev/tape /home &
nohup while true; do date; sleep 5; done  # fails! must be in a script

# FIND (modify time could be == create time if file is new)
find . -type f -amin -10 -print # files accessed in last 10 minutes
find . -type f -atime -2        # files accessed in last 48 hours
find . -type f -mmin -5         # files modified in last 5 minutes
find . -type f -mtime -1        # files modified in last 1 day (24 hours)
find . -type f -mtime -7        # files modified in last week
find . -mtime +3 -mtime -8      # a range of times (-a is optional)
find . -daystart -mtime 0       # files created since 12 midnight today
find . -daystart -mtime 1       # files created since 12 midnight yesterday (i.e. files NOT created today)
find . -mount foo               # to avoid /mnt/floppy
find . -type f -atime +30       # files that have not been read in 30+ days
find . -size 42c                # files exactly 42 bytes
find . -maxdepth 1              # only look in CWD, do not recurse (i think)
find . -name foo -prune         # don't recurse
find . -path '*bqh0'            # directories with the word 'bqh0' at the end
# Canonical find - what changed during the last week?
find . -mtime -7 -type f -print0 | xargs -0 ls -lt

#                               important
find . -name '.*\.sw*' -exec rm -i {} \;  # eliminate swp,etc. swapfiles
#                                    ^
find mydir/ -name *foo* -exec ls -l {} \;
find mydir/ -name *foo* | xargs ls -l

# Verify first...
find . -maxdepth 1 -name '*avan*' -exec ls -l {} \;
# ...then move (do not recurse)
find . -maxdepth 1 -name '*avan*' -exec mv {} old/ \;

# Copy all the files in a directory tree into one, large directory:
find . -type f -exec cp -p {} /newdir \;

# Call find(1) recursively to find everything named junk* that is not a dir:
find -name 'junk*' ! -type d -exec find {} \;

# Sum file sizes using awk
find . -name '??03*' | xargs ls -l | awk '{s+=$5}END{print s}'
# Sum file sizes WITHOUT using awk.  Shell's SET creates numbered variables for each whitespace-separated element, size happens to be in position $3
t=0; for f in $(ls); do set -- $(ls -lgo $f); ((t=$t+$3)); done; echo $t
# Sum file sizes using awk - safe for spaces in filenames
find $PTHMAP -maxdepth 1 -name '*.xls' -print0 | xargs -0 ls -l | awk '{s+=$5}END{print s}'

# Show only files starting with b, c or containing 'part' somewhere in the name:
ls foo.{b*,c*,prc,*part*}
# or count specific filetypes
ls {*htm,*xls} | wc
# but for find(1), must do this:
find -name '*.txt' -o -name '*.sas'
find -name '*.txt' -o -name '*.sas' -a -not -name '' -a -not -name 'foo*'
FILES=$(find $PTHCODE -type f -not -name baseline.md5 -a -not -name '*.log' -a -not -name '*.lst' -a -not -name '*.txt')

# Do certain filetypes exist in a directory?
PDBSEXIST=$(find "$PDB" '*.pdb' -type f -printf "%s" 2>/dev/null)
if [ -n  "$PDBSEXIST" ];then ...

# Use precise range minutes to find timestamp files older than 4:10pm and newer than 4:19pm using tempfiles (mmddtttt)
touch -t 02191610 /tmp/f1 && touch -t 02191619 /tmp/f2
find . -newer /tmp/f1  ! -newer /tmp/f2 -print
# Or for finding files between datestamp June 26 and June 30:
touch -t 200406260000 /tmp/t1 && touch -t 200406300000 /tmp/t2
find . -newer /tmp/t1 ! -newer /tmp/t2

# Watch, poll, directory for new files (but won't notice files copied with
# older timstamps TODO)
touch /tmp/f1 && while true;do find /home -newer /tmp/f1 2>/dev/null;touch /tmp/f1;sleep 5;done

# Canonical touch file time stamp date stamp datestamp.
touch -d 'May 2 2008 15:03' foo.txt
touch -d "Sep 24 2006" foo.txt
touch -d "Sep 24" foo.txt
find . -not -name '*co'|xargs touch -d 'Mar 24 2011 13:26'
touch '\\rtpsawnv0312\pucc\VALTREX_Caplets\INPUT_DATA_FILES\tmp\DPRunFlg.txt'
touch  //rtpsawnv0312/pucc/VALTREX_Caplets/INPUT_DATA_FILES/tmp/DPRunFlg.txt

# Recursive touch
$ find . -type f -mtime -40 -name '*sas' | xargs touch
# Recursive touch(1) for dirs that might have spaces in names
$ find from -print0 |xargs -0 touch

# Troubleshoot a disk full error (find the largest big offending file):
find / -type f -size +1000000c -exec ls -l {} \; 2>/dev/null | grep -v "/proc"
# or find largest file:
find / -xdev -size +1024 -ls | sort -r +b

# Find files in the /tmp directory that are larger than 10 megabytes that
# have not been modified in the last 48 hours (for GNU, c means use bytes):
find /tmp -size +10000000c -and -mtime +2

# Use the rotate utility if a logfile gets to be 2MB or larger:
find . -name access.log -size +1900000c -exec rotate {} \;

# Tarball files in CWD created in the last 24 hours:
find -mtime -1 -type f | xargs tar cvfz junk.tgz

find -name *.PDF -type f | xargs gtar cvfz junk.tgz

# Tar only the top level directory, skip do not tar subdirectories:
find mydir -maxdepth 1 ! -type d -exec tar cvfz bobh.tgz {} \;
find mydir -maxdepth 1 ! -type d  | xargs tar cvfz bobh.tgz

# tar(1) is a bitch when it comes to specifying files, use this instead:
cat my_FullyQualified_filelist.txt | xargs tar cvfz onlyspecificfilestarred.tgz

find -type f -mtime -1|xargs tar cvfz foo/t.tar.gz && scp foo/t.tar.gz bheckel@daeb:~/tmp/

# Recursive grep (if no GNU -r available and even that doesn't always work):
find . -name '*.h' -exec grep -H foostring {} \;
# or better recursive grep
find . -type f -print | xargs grep foo
# or                                   discard STDERR
find . -type f -print | xargs grep foo 2> /dev/null
# or all text _without_ specifying which file(s) the text came from:
find . -type f -exec grep -i foo {} \;
# or all text specifying which file(s) the text came from (filename will be
# below the find results):
find . -type f -exec grep -i foo {} \; -print
# or, just the filenames.
find . -type f -exec grep -il foo {} \;

# Find, prompt, then remove if y.
find . -inum 123 -ok rm {} \;
# or
find . -inum 123 | xargs rm -i;
# or
find . -inum 123 -exec rm -i {} \; 
# or find and remove core
find -name core -exec file {} \; -exec rm -i {} \;

# Recursively update timestamps on all files and directories from current one downward:
find . | xargs touch

# To find setuid and setgid file on your system.  Spaces around parens are mandatory, the -a isn't.
find / -type f -a \( -perm -4000 -o -perm -2000 \) -print
# Find test files except for test.log:
find -name 'test????' -a ! -name '*.log'

# To find file permissions writable by everybody chmod 777 (but not symlinks)
find / -type f -perm -2 -print 2>/dev/null
find / -perm -0600   # finds -rw-r--r--  ??TODO

# Find all cad files from PWD down and copy them to newdir, preserving their
# properties (try to keep newdir/ out of the same directory level or you'll
# get a bunch of "foo.cad and foo.cad are identical" messages):
# Test first:
find . -name '*.cad' -exec echo {} newdir \;
# Then run:
find . -name '*.cad' -exec cp -p {} newdir \;

# Collect all user's .bash_history files
find / -type f -name .bash_history | xargs cat > /tmp/history.txt

# Find all dead symlinks:
find . -type l -print | perl -nle '-e || print'
# or remove them
find . -type l -print | perl -nle '-e || print' | xargs rm

# Non-GNU find is restricted to finding entire filenames.  Use this to search
# partials (note wildcards must be within quotes):
find / -print | grep 'fin.*me'

# Throw away 'Permission denied', etc. by dumping STDERR to null.
find / -name foo 2>/dev/null

# Do something to specific filetypes:
$ find -name '*.pl' -exec chmod 755 {} \;

# Find files modified on May 21
ls -Al | grep 'May 21'
# Find files modified at 12:09
ls -Al | grep '12:09'

# Test parallel printer (as root): Use Ctr-V Ctrl-l to get the ^L.  It sends a
# form feed to eject the paper.  Type the quotes around it literally.
echo "This is a test." > /dev/lp0
echo "Please ignore this print job." > /dev/lp0
echo "^L" > /dev/lp0

# Unique elements (same as sql SELECT DISTINCT foo ...). MUST BE SORTED FIRST.
$ sort junk | uniq > junkout

# Count number of blank (including whitespace chars) lines in Unix fmt textfile (see vi solution for better answer):
cat foo.txt | awk ' /^['\ '|'\\t']*$/ { ++x } END{ print "Blanks = " x } '

# Create patch(1) - stand in common parent directory of lao tzu:
diff -Nrup lao tzu >t.patch
# Install patch:
patch <t.patch lao  # lao tzu are identical now
# Reverse patch:
patch -R < t.patch  # lao tzu differ again

# Fix a manpage.  The sed script has lines like  s/\.YODLTAGSTART\./\r\.YODLTAGSTART\./g
$ sed -f mysedpatchscript.sed /tmp/rxvt.1 > /usr/man/man1/rxvt.1

# Show others what you're doing on your terminal (demos, etc.).  Poor man's VNC.
bash 2>&1 | tee /tmp/demo      <---you
tail -f /tmp/demo              <---them

# Only important errors and track logfile from same tty that you're working:
tail -f /home/apache/logs/error_log | grep -v 'apache/icons/' &
tail -f /home/apache/logs/error_log | grep -v 'apache/icons/' 2>&1 | tee tail.log

# Do something if the shell receives a signal:
trap 'echo footrapped;' 1 2 3 15
# or
trap 'rm -f footrapped.txt; exit;' 1 2 3 15

# Use the user's PAGER if set, use more(1) otherwise.

# Delete all except saveme.txt (a regex) from a directory (GNU ls only):
ls -I saveme.txt | xargs rm
# Wildcard list all files except FF* MF* NF* 
ls -I '[FMN]F*'
# Wildcard find everything except the file emacs:
find . -not -name emacs
# Wildcard open everything in the directory except file
vi [^]*

# Untarball using bunzip2 (bzip2) instead of gzip:
bunzip2 linux-2.4.3.tar.bz2 | tar xvf -
# or if available just
tar tvfj jdk118_v3-glibc-2.1.3.tar.bz2 

# Redirection
mycommand >&0   <---STDIN  same as 0> I think
mycommand >&1   <---STDOUT  same as 1> I think
mycommand >&2   <---STDERR  same as 2> I think

# mod modulus division
bc -lwq    # if need modulus, from within bc, set scale=0

# Run through base 2 decimal values using C-like syntax.  Prints 2, 4, 8, 16.
for ((i=1;i<5;i++));do echo "2^$i" | bc;done
# better
for ((i=1;i<=32;i++)); do echo -n "2^$i: "; echo "2^$i" | bc; done

# Enable bc floating point e.g. 42.123
set scale=3

# Command line on the fly bc calculation
(echo scale=5; echo 6954/10) | bc

# Command line bc base 10 decimal to hex conversion (bc is case sensitive for hex numbers!):
(echo obase=16; echo 10) | bc  # A
# Command line bc onvert hexadecimal to decimal in bc
(echo ibase=16; echo DEADBEEF) | bc  # 3735928559

# Binary addition subtraction multiplication division in bc:

# Similar to foo=`ls -l` but linefeeds removed.
foo=`eval ls -l`; echo $foo

# ls -l shows "total" for a directory.  It represents the number of blocks
# (e.g. blocksize is 1024 for Cygwin) for all files in that directory.  So any
# file with 1 or more bytes will add "1" to total's total.  E.g. a file with
# size 0 will show "0", a file with size 1024 will show "1", with size 1025
# will show "2", etc.
# TODO what does the subdirectory size mean during a ll ? not the same pattern.

# Find size of certain files in dir:
wc [d-h]* 2>/dev/null | grep total | awk '{print $3}'
# Find library required e.g. '...shm1.c: undefined reference to `shmget''
# Must cd to /usr/lib... first.
# Then add -lcygipc to end of gcc command line in this IPC case.
# TODO automatically search /usr/lib/, /usr/lib/ ...
for i in 'lib*.a'; do echo $i; nm $i | grep shmget | grep -v UNDEF; done

# Vertical instead of horizontal cat
echo -n "hello world" | dd cbs=1 conv=unblock 2>/dev/null

# Write specific range of chars to a new file:
dd if=bladerun_crawl of=junkcrawl bs=1 skip=2 count=3

# Uppercase all characters in a file:
dd if=foo.txt of=foo.upper.txt conv=ucase
# or lowercase
dd if=foo.txt of=foo.lower.txt conv=lcase
# or
cat foo.txt | tr '[a-z]' '[A-Z]' > foo.upper.txt
# or lowercase
cat foo.txt | tr '[A-Z]' '[a-z]' > foo.lower.txt

# Three methods of deleting filenames containing spaces.
$ rm *\ *   $ rm *" "*   $ rm *' '*

# Remove a file whose name is blank or weird:
# Find inode
ls -i
# then rename using the inode (TODO can use mv {} with xargs??)
find . -inum 41734 -exec mv {} thenrmthisfile \;

# Find out types of files/executables in ~/bin:
for i in ~/bin/*; do file $i; done;

# Do something to all files of a specific filetype:
for f in `echo *.shn`; do shorten -x $f; done
# or better (depending on the shell)
for f in *.shn; do shorten -x $f; done

# Find multiple pattern filenames and open all in vi
vi `find . -name '*merge*' -o -name '*join*'`

# Simple find and edit search string "bobh" in one swoop (like my bgrep but without duplicate filenames):
vi `find . -name "*" -exec grep -l "bobh" {} \;`
# or just show filenames:
find . -name 'dlt*' -o -name 'tst*' -exec grep -l REVISER {} \;
# Find regex bobh or babh, etc. in all html docs, then edit each with vi.
vi `find . -type f -name "*.html" -print | (xargs grep -il "b[a-z]bh" 2>/dev/null)`
vi `grep -[r]il findthisstring *.html 2>/dev/null`

# Find and edit vb source files in one swoop - good for code review:
find -mtime -7 -type f -name '*.vb' -print0 | xargs -0 vi  # DON'T USE ...| xargs vi -
# May be easier to edit the .tgz in vim:
find -mtime -7 -type f -name '*.vb' -print0 | xargs -0 tar cvfz junk.tgz

# Find newish files without a 'generated' string and prepare them for a code review form
# e.g. LotTracking/LotTracking/ASPNETWebApplication/Banner.ascx.vb,Jul-29-2009 13:47
$ find LotTracking/ -name '*.vb' -mtime -90 -print0 |xargs -0 grep -RZL 'This code was generated by a tool' | xargs -0 ls -l | awk '{print $9","$6"-"$7"-2009 "$8}' >|t.csv

# Execute a remote shell command at a remote machine.
rsh hp10 ls /tmp
# this will result in the current box sending a message to hp10 to run ls
# In order to do this, you need to tell hp10 that it is OK to accept commands
# from you at hp8 without asking for a password. You can do this by including
# a line:   <---fully qualified
# in a file ~/.rhosts in your home directory at hp10. 

# Can't get Cygwin's smbclient to work with -U so do this first:
export USER=packland\\heckel%new2day
# Then, to retrieve to CWD.
smbclient //pack-web/shpdrpts -c 'get shpdbom.txt'
unset USER

# Change owner and group simultaneously:
chown oracle.dba /u01  (or oracle:dba)

# Mount CDROM
mount -t iso9660 /dev/cdrom /mnt/cdrom

# To pad with leading zeroes:
gawk 'BEGIN {printf "%10.0g\n",3.14; exit}'

# Trap window resize:
kill -l    <---to find the number for SIGWINCH
trap "echo caught SIGWINCH" 28
# then resize the window

# Trap Ctrl-c:
trap "echo caught SIGINT" 2

# Send mail from command line:
echo 'testing' | /bin/mutt -s "subj line"

# Cygwin.  Place a file's content's onto Clipboard:
cat junk.html | putclip
# Cygwin. Place Clipboard contents into a file:
getclip > junk.txt
getclip | wc

# Skip binaries (GNU's grep is usually fine without this):
grep bobh `file * | egrep 'script|text' | awk -F: '{print $1}'`

sed 's/day/night/' <old.txt >new.txt

# sed acts like grep but just prints the line
sed -n '/LADE/p' bladerun_crawl
# Simple awk (acts like grep but just prints the line):
awk '/LADE/ {print $0}' bladerun_crawl
# Preview, debug, lines that will change:
sed '/eplic/{p;s/eplic/XYZ/}' bladerun_crawl

# Print only specific range lines 2, 3, 4 and 5:
sed -n '2,5p' bladerun_crawl
# Delete specific line numbers:
sed '2,5d' bladerun_crawl
sed '2,3d;7,8d' bladerun_crawl

# On lines containing the word 'were', do a double substitution:
sed '/were/{s/Repli/RAPLI/;s/not/two!!!/}' bladerun_crawl

# Make changes and save just changed lines to file for debugging:
sed 's/Repl/XXX/w junkchanges' bladerun_crawl

Double space doublespace a file:
sed G foo.txt
awk '{print ; print ""}' foo.txt

# Remove all double quote quotation marks.
$ sed 's/"//g' foo.txt > dequoted.txt
# or remove all double quote quotation marks in place.
cat foo.txt | sed 's/"//g' >| foo.txt

# Split on, parse, colon delimited file:
awk -F: '{print $1 " and " $2}' /etc/passwd
# Same
perl -ne '@x=split /:/; print "$x[0] and $x[1]\n"' /etc/passwd

# Print the entire line, $0, if the second field contains 'John' or 'Fred'.
awk '$2 ~ /John|Fred/ {print $0}' foo.txt

# cat file until first blank line:
awk '$0 ~ /^$/ {exit;} {print $0;}' bladerun_crawl

# Extract lines containing the word COUNT.  Like grep.
awk '/COUNT/' foo.txt ...
# same as the more verbose
awk '/COUNT/ {print}' foo.txt ...

# Shift first entry to last entry (rearrange columns).
awk '{print $2, $3, $4, $1}' resortme.txt

# Find bash user's real names
awk 'BEGIN{FS=":"} $7 ~/bash/ {print $5}' /etc/passwd
# Better
awk -F: '$7 ~ /bash/ {print $5}' /etc/passwd

rpm -qip foo.rpm          # query
rpm -qf /usr/sbin/bind    # give the installed pkg name & num
rpm -Uvh foo.rpm          # install
rpm -qa | grep -i pine    # determine if a pine RPM has been installed
rpm -e emacs              # remove

Athena scrollbars:
High left mouse scrolls one line at a time
Low left mouse scrolls one page at a time
Right mouse scrolls down
Left mouse scrolls up
Middle mouse to drag the scroll bar up and down

# Select a range of rows.
awk 'NR < 5 {print}'
awk 'NR >5 && NR <11 {print}'

# Checkout a repository on a remote machine:
export CVSROOT=:ext:bheckel@parsifal:/home/bheckel/repository
cvs co eandb

# Debian (at least) date undocumented set time (as root):
$ date --set=17:03:01

# Determine how much memory (in MB) you have:
$ free -m
# or 
# vi /proc/meminfo
# Determine how much swap (in MB) you have on Solaris:
/usr/sbin/swap -s
# Determine how much memory (in MB) you have on Solaris:
prtconf -v | grep Memory
# Determine what platform you have on Solaris:
isainfo -v
# Determine processor you have on Solaris:
psrinfo -v

# Determine the maximum non-swap memory (in MB) you have on Solaris:
/usr/sbin/prtconf | grep Mem
# Vendorid/deviceid
prtconf -pv

# Echo text in color (type " then Ctrl-V Esc then [0;31;40mThis Is In Red")
# This won't copy 'n' paste.  See ~/code/misccode/prompt_colors.txt or .bashrc
echo "#[0;31;40mThis Is In Red with a Black Background"
echo "$fg_cyan ---------------------------------------------------$normal foo"

A reasonable xterm font:

Cygwin/Linux - to get man -k working, must run makewhatis
Solaris - to get man -k working, must run catman.

# Remove, extract or delete a column in a tab-delimited file if awk cannot:
# Cut a specific range of bytes and sum them (assuming they're numeric):
cut -b10-12 test.dat | sumlist
# Cut a specific part of a line of text (assumes you know number of fields):
echo 'foo bar baz' | cut -d' ' -f1     <---rets foo
echo 'foo_bar_baz' | cut -d'_' -f1     <---rets baz
echo 'foo bar baz' | cut -d' ' -f1-2   <---rets foo bar
# Compare awk and cut (or use Excel after naming file foo.xls):
$ jobs | awk '{print $1}'
# same (do a Ctr-v between the quotes if data is tab-delimited):
$ jobs | cut -d' ' -f1
# Can't do this with cut if you don't know your total number of fields:
echo 'foo bar baz' | awk '{print $NF}'
echo 'foo:bar:baz' | awk -F: '{print $NF}'
# And you sure as hell can't do this with cut to get the next-to-last field:
echo 'foo bar baz' | awk '{print $(NF-1)}'
echo 'foo:bar:baz' | awk -F: '{print $(NF-1)}'
# But you can't easily rebuild a tab-delimited file with awk so do this:
head TransactionDetails.dat | cut -d'	' -f2-4

# Determine if disk is almost full (on Debian Linux):
df -m|awk '{if ($5>=70 && NR>1) print $5,"      " $6 }'

# Remove files based on specific date of Jun 12 (GNU ls):
rm -i ` ls -Al | grep "Jun 12" | awk '{print $9}'`
# Or remove all files except for specific date of Jun 12 (GNU ls):
rm -i ` ls -Al | grep -v "Jun 12" | awk '{print $9}'`
# or just list files (note need 2 spaces for single digit date) modified on a
# specific date:
\ls -AlR | grep "Nov  7" | awk '{print $9}'

# Sort all files created in August by size (col 4, numeric):
ls -l | grep "Aug" | sort +4n

# Poor man's recursive ls:
for i in builddir datadir;do cd $i; ls; cd ..; done

# List all filesystems (e.g. /dev/sda2 ...)
df -k | awk '{print $1}' | sed -n "3,14 p"
# List all *supported* filesystems
cat /proc/filesystems

# Find your MAC address on Debian (via the network, not the card itself).
/sbin/ifconfig eth0       <---shows HWaddr
# or to find daeb's MAC address from a W2K box:
ping daeb
arp -a

# Don't copy backup .bak files
cp OpenRefreshSave.*[^bak] ~/code/vb/

# To format floppy:
mkfs -t ext2 /dev/fd0                <---at least Linux
fdformat -U -H                       <---at least Solaris, formats
newfs /vol/dev/rdiskette0/7alfprodu  <---at least Solaris, creates filesystem
volcheck                             <---at least Solaris, creates /floppy
cd /floppy/floppy0                   <---Windows formatted floppy is ok
eject floppy                     <---when done, don't need volume manager GUI

# Zero out (empty) a file, leaving zero bytes
>| wipeout.txt

# Combine and compress two files (better compression than using -c)
cat open_write.c | gzip >foo.gz

# mod modulus division
E.g. 3 % 2 = 1    i.e. flip it 2/3 taking the remainder which is 1
E.g. 2 % 3 = 2    i.e. flip it 3/2 taking the remainder which is 2

# Rename files with spaces in their names:
for i in *; do mv "$i" `echo $i | sed 's/ /_/g'`; done
# or recursively rename files with the word 'one' in their name:
for i in `find -name '*one*'`; do mv "$i" `echo $i | sed 's/ /_/g'`; done

# Date calculation - add one day to today
echo `date +%s` + 86400 | bc
# Compare convert Unix and SAS epochs (10 years apart):
date +%s;echo `date +%s` + 315569520 | bc
# Convert a string date to a Unix datetime number.  Go from words to numbers.
date +%s -d'05/12/1998'
# Convert a string date to a SAS datetime number.  Go from words to numbers.
echo `date +%s -d'05/12/1998'` + 315569520 | bc

# Simple sum a column
cat tmpsas.2060.lst | awk '{ sum += $1 } END { print sum }'
# Sort then sum a column
sed 's/[)(]//g' junk | awk '{print $2}' | sort | xargs | sed 's/ /+/g' | bc
# Sum disk sizes:
df | tail -6 | awk '{print $4}' |  xargs | sed 's/ /+/g' | bc
# Best summing of single column (elim trailing '+' problem):
du -sk  *.sas7bdat|awk '{sum += $1} END {print sum}'
# or not summing all lines:
cat foo.txt | awk '/OnlyTheseLines/{t+=$1} END{print t}'
# or sum list
for u in bxj9 cmc6; do du -sk $u|awk '{print $1}'; done | awk '{t+=$1} END{print t}'

Poor man's editor (create new file only) using HEREDOC:
cat > myfile.txt <<.    <---<CR>, then type, then end with . on it's own line

# Print user id who created file
ls -l | grep foo | awk '{print $3}'
# same (faster?)
ls -l | awk '/foo/ {print $3}'

# Create tarball of all files in pwd that contain string 'ESSENTIAL':
tar cvfz ~/tmp/essential.tgz `grep 'ESSENTIAL' * | awk -F: '{print $1}'`

# Determine total size of selected files.  Add sizes of files together.
wc *.txt

# Find lines that have string '21' in column position 7 and 8 (assumes file
# too big for vi).  The '^' is important!  This is better than the 
# perl database approach above b/c you can pipe to wc to get a count.
sed -n '/^.\{6\}21/p' BF19.ZZX0166.MORMER
Find lines that have a blank where ALIAS should be then find the records with
February deathdates then count the number of records:
sed -n '/^.\{46\} /p' MORMER | sed -n '/^.\{48\}02/p' - | wc
Find NJ residents who died in July:
sed -n '/^.\{46\} /p' MORMER | sed -n '/^.\{48\}07/p' - | sed -n '/^.\{73\}31/p' - | wc
Same approach using Perl (perl -ne wraps an implicit loop around the file):
perl -ne 'print "1\n" if /^.{287}Y/' NATMER |wc
# Specific column.  If the file is small enough, repeated global commands in
# Vim database searching is easier:
:g!/^.\{46}02/d   <---do not skip the '^'!

# Like a database query subtotals counts by group i.e. proc freq textfile:
for i in `seq -w 01 57`; do echo -n $i:; sed -n "/^.\{76\}$i/p" foo.txt|wc -l; done
# Then drill down to view subset of state 14:
sed -n "/^.\{76\}14/p" fri2.txt >| small.txt

Delete the first 42 columns from a textfile:
sed 's/.\{42\}//' foo.txt
1,$s/.\{42\}//              <---from within ed

More readable environment variable output:
echo $PATH | tr ":" "\n"

Substitute only the second appearance of a string on a line:
sed 's/replaceme/FOO/2' foo.txt     <---don't think can do in vi

Compress 2 or more spaces:
echo 'long   str' | sed 's/ \{2,\}//'

# Make sure user is root:
val=`id | sed 's/uid=0(.*/ROOT/'`; if [ "$val" != "ROOT" ] ; then ...

Translate EBCDIC to ASCII
dd if=myinfile.txt of=myoutfile.txt ibs=800 cbs=80 conv=ascii
or maybe
dd if=myinfile.txt of=myoutfile.txt conv=ascii
then convert back to EBCDIC
dd if=myinfile.txt of=myoutfile.txt conv=ebcdic
SAS Note: tabdelimited FTP transfers to mainframe do not need to be converted.
ISPF will warn about unprintable crap but it's ok.

Simple canonical zip - comes FIRST in parameter list (original is left unchanged!):
zip foo.txt
zip *
Simple canonical recursive zip
zip -r flop/

# Find longest maximum widest line length in all textfiles. Subtr 1 if ff=dos:
$ cat *.txt | awk '{ if (x<length()) x=length() } END{ print x }' 
# Or if want individual max line lengths:
$ for f in *.sas; do echo $f; cat $f | awk '{ if (x<length()) x=length() } END{ print x }'; done

Get the value of the last parameter passed into a korn shell script.
eval last=\${$#}

Find the Windows PIDS (from within Cygwin), not just the Cygwin ones (good for
using  $ winkill 123 ):
ps -W|grep -i rtv

# Ignore all whitespace (the -c context is always good idea).  Best diff outside of vi -dR 1 2:
diff -cw f1.txt f2.txt

# Find info on Internet ports:
netstat -nl --inet

Which modules have been compiled-in an Apache webserver:
/usr/local/apache/bin/httpd -l

Determine runlevel on RedHat:
Determine runlevel on Solaris:
who -r

Cycle among virtual consoles: Left Alt+[left or right arrow]

# Unix heredoc here doc:
ok blah blah, this could extend many lines

  libname l "$UTMPDIR";data l.${2}BKUP(genmax=${4});set l.${2};run;

# Find alphanumeric characters using character class:
grep [[:alnum:]] foo.txt
grep [A-Za-z0-9] foo.txt

# Numeric character class
echo 19 | sed 's/[[:digit:]]/x/'

# Is a process running (in this case SAS)?
while true; do ps -W | grep sas; date; sleep 3; done
# Better
$ sas &;  wait %1; echo "SAS process terminated"

# Throwaway skip delete remove first 3 lines of a file:
tail -n +4 foo.txt
# or 
cat foo.txt | awk "{if(NR>3)print}"

Test procmail regex:
$ echo 'to:,' | egrep '^to:.*bhe[a-zA-Z]+@(worldnet)*'

scp _muttrc.otaku
scp rsh86800@rtpsh004://var/adm/scripts/ .

Use adduser in preference to useradd (at least on Debian)

# Combine mkdir with chmod:
mkdir -m 755 foodir

# Print column 3 if column 1 matches Ian (a database-like search):
awk '($1=="Ian") { print $3 }' foo.txt
# compare with Perl's
perl -ne '@f=split; if ($f[0] eq "Ian") { print "$f[2]\n"}' foo.txt
perl -ane '@x=split /\|/;print $x[0], "\n";' foo.txt

# Exit emacs (hopefully never to return...)
Ctr-x Ctr-c

# Syntax check the Apache config file:
/usr/local/apache/bin/apachectl configtest

# Is a package properly installed on Sun Solaris:
/usr/sbin/pkgchk -l -p `which gcc`

# A one time cron(1), at(1)
at 17:09 today            #<---press enter
echo 'foo' >/dev/console  #<---type commands followed by ctr-d

# Find dead webpages based on a space delimited textfile of users:
for u in `cat users.txt`; do lynx -dump "$u/"; done | m

# Canonical recursive websuck mirror
wget -m -np  ''
# gets linked pages, puts all in toplevel dir
wget -m -p -np ''

# Follow only relative links and skip GIF images:
wget -m -L --reject=gif

# Pretend to be IE
wget --header="User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)" http://msie.only.url/here

# Loop in sh shell:
while : ; do echo bob; sleep 6; done

# Create several simple dummy files:
for i in 1 2 3;do echo "i am $i" >foo$i; done

# Sequence
for i in `seq 5`; do mem; sleep 3; done

# Display terminal output on two xterms simultaneously (untested):
sh -c "$prog|tee -a $mytty" 1>$othertty 2>&1 0>$othertty

# Append two files vertically side by side:
paste -d' ' foo1.txt foo2.txt

ifconfig eth0 down
ifconfig eth0 up
route add -host eth0
route add default gw eth0

# Find and tarball only textfiles:
file -F '' * | grep text | awk '{print $1}' | xargs tar cvfz bin.tgz

# Without an enlightened tar xvfz or gtar e.g. Solaris tar gunzip:
gunzip <stable.tar.gz | tar xvf -
tar cf - findutils-4.1-srcdir | gzip >compiled.bobh.tgz
# Unenlightened tar that was compress'ed 
uncompress <Oct08.tar.Z | tar tvf -

# Environment variable check - use $VISUAL or $EDITOR or vi:

# Check valid users via FTP:
for u in bxj9 ckj1 ; do echo "testing $u "; ncftp -u $u -p dAebrpt5 rdrtp; done

ncftp -u myuid -p mypasswd

# Force Apache errors to syslog Solaris at least:
*.err;kern.notice;auth.notice;daemon.notice   /dev/sysmsg <---/etc/syslog.conf
ErrorLog syslog:daemon                              <---/etc/apache/httpd.conf

# man replacement (Solaris, not Cygwin):
nroff -man smbd.8 | more

# Broadcast message to all users:
wall < mywallmessage.txt

/sbin/init 0  # shutdown to allow poweroff
/sbin/init 6  # reboot w/o going to BIOS
# or fancy assuming you have users logged in
shutdown -g120 -i0 -y "shutting down server"   <---at least Solaris

# Convert DOS path to Unix path
cygpath 'c:\Documents and Settings\Bob Heckel'
ls `cygpath 'c:\Documents and Settings\Bob Heckel'`
vi `cygpath 'c:\temp\cygwin.txt'`
notepad.exe "$(cygpath -aw "Desktop/Phone Numbers.txt")"
javac -cp "$(cygpath -pw "$CLASSPATH")"

ufsdump 0uf /dev/rmt/0ubn /home  <---initial
ufsdump 9uf /dev/rmt/0ubn /home  <---incremental

# Solaris Volume Management:  $ eject cdrom  If used paperclip must:
/etc/init.d/volmgt stop; /etc/init.d/volmgt start
# Insertion of a floppy disk (UNIX� or MS-DOS format) has to be communicated
# to the Volume Manager manually:

# If ls -lS isn't available:
ls -l | sort +4r | grep -v "total"

# Give multiple users the same group and password:
$ useradd -g daebstat -m -p N6lPzsXhb5TLg dwj2

$ mailx -s 'email subject type CTRL-D or dot on blank line to end' root@daeb
$ mailx -s "mysubject" -r -c '' '' <junk
? touch *    # mark all as read and write to mbox in mailx...
mailx -f ~/mbox   # ...and read them
ssh rtpsh005 'ls -l /home/gaaadmin/GAAAdapter/gaa/receive/Output_Data | mailx -s 'subject''

59 5 6 * * mailx -s "Automated reminder from Bob" </arpa/af/b/bheckel/mailxmsg.txt

# Watch file sizes using cron and email every day at 2:05
5 2 * * * find /apache/logs/access_log -size +10000000c  | mailx -s "file is getting too big"
# Rotate if filesize is half a gigabyte or larger:
15 4 * * * find /opt/apache/logs/access_log -size +500000000c && /opt/bin/rotatelog

# Monitor system status (Solaris at least):
echo `uptime|awk '{print $11 $12 $13}' && df -k|grep /data|awk '{print $5}'` | mailx -s "load and /data space [cron tstdev]" ''

# Without an external file redirected in:
$ echo 'ok' | mailx -s 'test4'

# Group specific files for move to another machine.  Don't use find before tar
# unless your tar can do this (-I for Solaris)!!
cd /home; find . -name '*.PDF' -print | tar cvf pdfz.tar -T -
# Do this instead (TODO overflow if num files is too hi??)
cd /home; tar cvf /tmp/pdfz.tar `find . -name '*.PDF' -type f -print`

awk '/#/ {print "Got a comment SOMEWHERE in the whole line"}' /etc/hosts
awk '$1 == "#" {print "got a lone, leading pound sign"}' /etc/hosts
awk '$1 ~ /#/ {print "got a pound sign, SOMEWHERE in column 1"}' /etc/hosts
awk '/#/ {print "Found a comment"} $1 == "#" {print "Found comment in first column"} /^# /  {print "Found comment at beginning"} ' /etc/hosts
# Find the highest number of columns (i.e. fields, words) on one line in a file:
awk 'BEGIN{max=0}{cols=NF;if(cols>max){max=cols}}END{print max}' ~/bladerun_crawl 
awk '/^(From:|Subject:)/{print $2,$3,$4"\n"}' PotentialSpam | m

# bash enhancement like basename()
echo ${the_var%.*}   <--- amanuensis
# or for mainframe transfers where you don't want the .sas extension on mf:
for f in *.sas;do bfp $f "bqh0.pgm.testlib(${f%.*})"; done

# Unback restore more than one file:
for f in *.bak; do cp $f ${f%.*}; done

# HTMLify recently created files:
find /home -newer /tmp/f1 -name '*PDF' 2>/dev/null | perl -ne "print if s#......(....).............(.*PDF)#<A HREF=\1/\2>\1 \2</A><BR>#" >| /home/bheckel/public_html/email_down_list.html

# Which package did a file come from (Solaris):
grep /my/missing/file /var/sadm/install/contents

# Tape drive swap tapes
mt rewind; mt offline

# Solaris patches information
showrev -p 

# Nested for loop to build test directories:
for y in 2003 2004 2005; do for e in NAT MOR FET; do mkdir -p mvds/$e/$y; done;

# Print select paragraph (separated by blank lines) if word is found:
sed -e '/./{H;$!d;}' -e 'x;/team/!d;' bladerun_crawl
# Less unintelligible:
perl -ne '$/="";@p=<>;for $p(@p){print "ok $p\n" if $p=~/team/;}' <setup.ini

# Debug .bashrc trouble on Cygwin without sourcing config file clean bashrc
C:> bash -norc
C:\cygwin\bin\bash.exe --norc

# Switch uppercase to lowercase:
echo UPPERTOLOWER | tr [A-Z] [a-z]
echo UPPERTOLOWER | tr 'A-Z' 'a-z'
echo "THIS is a STRIng to be LOWErcased" | tr [:lower:] [:upper:]

# Lowercase a filename:
mv FOO.txt `echo FOO.txt | tr A-Z a-z`

# Lowercase an environment variable.  E.g.  export PS1=BAR  already set:
export PS1=`echo $PS1 | tr A-Z a-z`
export PS1=`echo "$LOGNAME@CDCJES2$ " | tr A-Z a-z `

# Uppercase all directories (assumes no files in the dir):
for d in *; do mv $d `echo $d | tr a-z A-Z`; done

# Cleanup projects dir before it gets backed up at night:
find ~/projects -name 'junk.*'|xargs rm

# Monitor a directory tree for new pdf files:
find /home -type f -name '*.PDF' -a -newer /tmp/fx -exec ls -lo {} \; 2>/dev/null
# Monitor a box for logons:
while true; do last|head|grep -v bheckel; sleep 60; done

# Monitor process load and get the cpu info you need that xload and uptime
# don't tell you
top -d 2 | col -b | grep states

# Print to syslog
echo 'as root print this message to console' >/dev/console

# Prompt user yn
read yesno; if [ $yesno = 'y' ]; then echo 'he said yes'; fi

# Find ls only hidden files
ls -a | grep "^\."

# How much disk space of quota is being used by user
/usr/sbin/quot /dev/dsk/c1t1d0s0

# Convert manpage to text:
man lp | col -b > lp.txt

# split(1) and rejoin 1MB pieces.  xaa and xab are max of 1.4MB to fit floppy.
# Works on binaries like .xls too.(make sure no x* files already exist in the
# directory):
split -b 1400000 orig.tgz
cat xa* > origrebuilt.tgz

# Original file is not saved.  And e.g. footext.gpg is readable in vim if use
# passphrase
gpg -c foofile # encrypt; gpg -d foofile # decrypt

# Recursive wc recursive find - safe for Windows filenames w/ spaces (Cygwin) canonical total count lines of code (alternatively use :vimgrep /foo/ **/*.vb)
find . -name '*.vb' -print0 | xargs -0 grep -i 'databound web'
find . -name '*.sas' -print0 | xargs -0 wc -l  # count lines

# File attributes - simple access in shell
unixtime=$(find foo.txt -printf "%AT" ); echo $unixtime
size=$(find foo.txt -printf "%s" ); echo $size

# Determine name of NIC
dmesg|grep eth

# Keep checking for job completion HFS
while sysout -v JOB15722|grep -c EXECUTION; do sleep 2; done

# Read file line by line in shell.  Feed textfile to a (single?) shell command.
while read f; do echo $f; done <myfile.txt
# Bulk upload converting extension on the fly upload to mf (fq paths ok)
while read f; do bfp $f "bqh0.pgm.lib(`basename $f .sas`)"; done <filelist.txt

# ROT13
cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M'   # "a" goes to "n", "b" to "o", etc.

# Primitive alarm clock
sleep `echo '60*2'|bc` && beep

# Delete all blank lines from last line to EOL:
sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba' foo.txt

# Find all files opened by a process (Solaris at least):
/usr/proc/bin/pfiles mypid

# Create and upload tarballs out of just text files in ~/code (probably s/b
# scripted)
for d in c html misccode perl sas vb; do cd $d && file -F '' * | grep text | awk \
'{print $1}' |xargs tar cfz ../$d.tgz && cd - ; done

for f in c html misccode sas vb; do scp $f.tgz; done

# Where are the files in this (properly installed) Cygwin package?
cygcheck -l apache

# Use a default if no parameter is passed via command line
BAR=notemptylikeFOOis; echo ${FOO-$BAR}  # use $bar if $foo doesn't exist

# Determine file size in bytes
filesize=$(find $1 -printf "%s" )

# use locate(1) to search, this to create (findutils package):
$ updatedb --prunepaths='/cygdrive /proc /tmp /var /home/bheckel/tmp'

# For .bashrc "loc" alias (good candidate for cron):
# alias loc='locate --ignore-case --database=/var/lib/locatedb.code '
$ /bin/updatedb --localpaths='/home/bheckel/code' --output='/var/lib/locatedb.code'
# On cygwin swiss:
$ /bin/updatedb --localpaths='/cygdrive/e/cygwin/home/bheckel/code' --output='/var/lib/locatedb.code'
# Linux
$ sudo updatedb --database-root='/home/bheckel/code' --output='/var/lib/locatedb.code'

# Calculate the day before assumes GNU date(1):
date -d '20050801 2 day ago' +"%Y%m%d"

Solaris 10 SMF rc file replacement
svcs -a   # which daemon services are running on Solaris 10:
svcs -x   # which failed to start
svcadm disable sendmail
svcs -v sendmail

# Compare two Word docs using a temporary fifo(?) pipe.  Probably bash only.
$ vi -d <(antiword 1.doc) <(antiword 2.doc)
$ vi -d <(antiword Client\ Feedback\ Report\ clm_ID0509_TXT.doc) <(antiword Ctwo.doc)

screen -r  # reattach screen
Ctr-a d  # detach (from within screen session)

# Set a shell variable's default even if it is not set, or is missing:
f=foo.txt; if test "x$f" = "x" && f=bar; then ... fi

# Push, flush history from one xterm to another
history -a  # append this xterm history
history -n  # read in the other xterms appended history

# Chain multiple sed substitutions together:
sed 's/^ind//i; s/\.sas7bdat//'

# Insert, append, add a header line to first line of an existing file:
for f in *.html; do echo "<b>$f</b>" >| new$f && cat $f >> new$f; done;
# or insert, append, add a header line to first line of a single new file:
for f in *.html; do echo $f >>100581.html && cat $f >>100581.html; done

# Print file name and first two fields 
for f in *.xls; do awk '{print FILENAME ": " $1 " and " $2}' $f; done
for f in *.xls; do awk '/search4me/{print FILENAME ": " $1 " and " $2}' $f; done
# Which CSV files contain the string SAPILYN?
for f in *.xls; do awk '/SAPILN/{print $1 ": " FILENAME}' $f|sort|uniq; done

# Don't need an eval()
bytes=$(find $TMPLST -printf "%s") ; if [ $bytes -gt 0 ];then echo 'ok';fi
timestamp=$(find arch.tar.gz -printf "%t" )

# Conditional find(1) on any files older than 60 minutes exist check
if [ `find $PTH2 -maxdepth 1 -not -mmin -60  -printf "%s"` ];then ...
# Conditional find(1) on any files newer than 1 day old check
BTCHS=$(find $PTHBTCH -maxdepth 1 -name '*.xls' -mtime -1) if ! [ -z "$BTCHS"  ];then ERRMSG="$PTHBTCH xls files are less than one day old" catchWarning break fi

diskpct=$(df /cygdrive/c|tail -1|awk '{print $5}'|perl -pe 's/%//'); if [ $diskpct -gt 98 ];then echo 'may have full disk';fi

crontab -e fields:  min hr day mon wkday(0=Sun)

# Encrypt simple
gpg -c foo.txt
# Decrypt simple
gpg -d foo.txt.gpg >foo.txt

# Solaris 10 dark background and source my .bashrc (from Console)
# /opt/sfw/bin/rxvt -rv -e bash&
# Cygwin black text on white screen
$ rxvt -bg white -fg black -geometry 80x40+159+46 -fn "Andale Mono-12"

# Typing speed
START=`date +%s`;WORDS=`cat|wc -w`; STOP=`date +%s`; SPEED=`echo "$WORDS / ( ( $STOP - $START ) / 60 )"|bc`;echo "You have a typing speed of $SPEED words per minute."

# Configure ssh for no password:
ssh-keygen -t dsa  # on mario
cat /home/chronos/.ssh/ | ssh 'cat - >> ~/.ssh/authorized_keys'

# Performance benchmark:
time echo "scale=5000; 4*a(1)" | bc -l -q

# Maximize / minimize rxvt font: Shift++ or Shift+- (+/- is using numeric pad with numlock on)

# Zip and remove original file on success
for c in 1 2; do zip lelim$ lelim$c.sas7bdat && rm -v lelim$c.sas7bdat; done
# Zip and remove original file on success (better)
for f in `find . -name '*.sas7bdat'`; do zip -mT $ $f; done

Human readable ctags listing:
$ ctags -x * > ctagsoutput.txt

Create ctags (Exuberant Ctags 5.2+ - only those files whose names are mapped to
languages will be scanned):
$ ctags -R <---probably  $ ctags *  for other versions, not sure how to recurse
Then Ctr-] and Ctr-t in Vim to navigate or find function whose name you only
know part of (assumes you've run ctags *):

sudo apt-get install samba

# Canonical awk
awk -F ' ' '{print $1}'  # -F ' ' is unnecesary
awk '{print $1}'

# Use colon as awk separator instead of default whitespace
awk -F ':' '{print $1}'

time w3m -dump bashref2_05.html &>/dev/null

# Decompress from pwd to another dir
unzip '*sumr*zip' -d ../tmp

# Just do a simple extract
unzip -jo lelimssumres01a$

# Date formatted using stftime
$ DATE=`date '+%Y%m%d'` DAY=`date '+%d'` HOUR=`date '+%H'` MONTH=`date '+%m'` MIN=`date '+%M'`
$ date +'%Y%m%d' # print formatted date (e.g. 20010622)
# or find Unix epoch time on a specific human date:
$ date +%s -d'Jul 7 2000'
# Make a local timestamped copy and zip only that new file
$ cp '\\rtpsawn323\SQL_Loader\Logs\LGI.log' LGI$(date +%Y%m%d%S).log; zip -ru . -i \*.log
# Backup a project to a share
$ p=ven;d=`date '+%Y%m%d'`;tar cfz $p.$d.tar.gz add_ventolin/ && cp -i $p.$d.tar.gz /cygdrive/u/ && rmv $p.$d.tar.gz
$ p=crc;d=`date '+%Y%m%d'`;tar cfz $p.$d.tar.gz callcenter/ && cp -i $p.$d.tar.gz /cygdrive/u/ && rmv $p.$d.tar.gz

# Print only a part, section, range, paragraph, of a file.  Paragrep.
awk "/^xxSASx START/,/^xxSASx END/ {print}" ~/code/misccode/oneliners
ipconfig /displaydns | awk "/rtpsh005/,/ {print}"

# Create backup filename with today's date datestamp
$ touch foo`date +%d%b%y`.txt
$ mv //{,Custody.`date +%d%b`.pl}

# Toss errors to the bit bucket
$ find / -name '*.mac' 2>/dev/null

# Reset, blank titlebar title bar
unset PROMPT_COMMAND; echo -ne '\033]0;\007'
# Change, write to, rxvt titlebar (won't work in a script, must paste to term):
unset PROMPT_COMMAND; echo -ne '\033]0;ora\007'
unset PROMPT_COMMAND; echo -ne "\033]0;${PWD}\007"

# For quick email attachment transfers across boxes (head gives dividers between each file)
$ head -n 1000000000 .inputrc .vimrc .bashrc ~/code/misccode/_vtorrc >|essential_combined.txt
$ find . -name '*.sas'|xargs head -n 10000000 >|

# Grow enlarge a file to copies of itself (especially good if Vim's undo whacks _viminfo when it gets huge)
for i in `seq 1 500`; do cp FW_ONLINE.txt $i; cat $i >> FW_ONLINE.big.txt; rm $i; done

# Fix backspace in shell (for vi)
$ stty erase ^H intr ^C kill ^K
# or sometimes ^? instead of ^H

# Update a production directory with newer files from dev (maybe this should be a script)
FR=/home/bheckel/tmp/junk26Jun08_1214509437/from; TO=/home/bheckel/tmp/junk26Jun08_1214509437/to; cd $FR && find -type f -mtime 0 -print0 | xargs -0 tar cvfz $TO/t.tgz && cd $TO && tar xvfz t.tgz

# Tampering check:
$ md5sum * > tampering.md5                        # build
$ md5sum * > check.md5; diff tampering.md5 t.md5  # check
$ md5sum * | diff - tampering.md5                 # better check

# Canonical sh bash if then else
if [ expression ];then commands elif [ expression2 ];then commands else commands fi

# Wrong number arguments parameters passed to shell script:
[ $# -lt 2 ] && echo "Usage: $0 arg1 arg2" && exit 1
[ $# -eq 1 ] || echo "Usage: $0 arg1" && exit 1
if [ $# = 0 ]; then ... fi

# Length of string is 1 character
if [ ${#month} -eq 1 ];then ... fi

# Shell string comparison: if [ 'x' = 'x' ]; then... fi
# Shell integer comparison: if [ 2 -eq 2 ]; then... fi

# Determine if a file has a certain suffix, extension (mnemonic # on keyboard is to the left, % is to the right).  Bash only.
if [ "${1##*.}" = 'tar' ]; then ... fi

# Untar single file from tarball
$ tar -x extract_only_me.txt -vf my.tar

CSVS=$(find $PTHPAR -maxdepth 1 -name '*.csv' -not -mtime 0)
if ! [ -z "$CSVS"  ];then echo files are stale ...

# Determine Cygwin version:
$ cygcheck -c | grep ygwi

Input/output IO redirection ( < and > ) connects processes with
files, while the pipe ( | ) connects processes with other processes. 

$ diff <(md5sum *.sas) <(cd tmp;md5sum *.sas)
$ diff <(md5sum *.mp3) <(cd /cygdrive/e/Decade/Disc\ 1;md5sum *.mp3)

# Yesterday's zip file
TODAY=`date +%b-%Y`
YESTERDAY=$(expr `date +%d` - 1)
echo "$PTHZIP/${YESTERDAY}-${TODAY}.zip"

# Remove leading zero:
$ date +%d | sed "s/0//"

# Substring first character:
$ if [ ${foo:0:1} = 9 ];then echo first char is 9;fi
# For ksh use sed (e.g. "NOTE: SYSCC: 0 ( ended: 17APR09:07:01:48 / minutes elapsed: 1.78826666673)" ) returns 1.78826666673
grep 'minutes elapsed' Valtrex_Caplets.log |awk {'print $11'}| sed 's/)//g'

# Not equal in bash
if [ $x != a ]; then echo not equal; fi

# ksh commandline completion - In vi-mode use <ESC> to control mode and then \ to complete or = to list.

# Is today Monday?  If today is Monday.  Use  !=  to negate.
if [ `date +%a` = Mon ];then ... fi

# Watch for process, send warning email if it's not there
ps -ae | grep lms_nmgr | grep -v grep | read pid && echo "process found `date`" || echo "Subject: LIMS down on ushp9h" | mail lmswatch@ussung9

# cal(1) for two month display
cal 06 2009; cal 07 2009

# Shell compare test: remember, strangely enough,  = is for comparing literal variables and -eq for integers.

sz=$(find $PTHQT -maxdepth 1 -name '*.jpg' -print0 | xargs -0 ls -l | awk '{s+=$5}END{print int(s/1000000)}')

# Parse run-time out of a string and calculate if it's within threshold
tm=$(grep 'minutes elapsed' //Rtpdsntp032/DataPostArchive/Ventolin_HFA/CODE/log/Ventolin_HFA.log|awk {'print int($7)'})
if [ $tm -lt 70 -o $tm -gt 95 ];then echo 'uh oh outside time threshold';fi

# Rename powerpoint files with today's datestamp:
d=`date +%d%b%y`; for i in *.ppt; do mv "$i" `echo $i |sed "s/^......./${d}/g"`; done

# Cygwin bash at least
export PS1='\u@\h\$ '
# HPUX ksh at least
export PS1=`whoami`'@'`hostname`' '

# Barebones modified /Cygwin.bat (DO NOT specify  -fg white, rely on .Xdefaults):
rxvt -sl 10000 +j +sk +si -bg black -fn "Andale Mono-13" -e bash --login -i
# Normal Cygwin.bat in a single line
@echo off & C: & chdir C:\cygwin\bin & start /B rxvt.exe -geometry 80x45+295+135 -fn "Andale Mono-13" -sl 10000 -sr -bg black -fg wheat -e /bin/bash --login -i

# Escape second and higher spaces (echo "cd /fo o/ba r" | sed 's/ /\\ /2' only gets 2nd one)
echo "cd /fo o/ba r" | sed -e 's/ /\\ /g' -e 's/cd\\/cd/g'

# Shell arithmetic addition:
$increment = `expr 42 + 1`

# For each file, do something to it like remove carriage returns using temp files:
for file in $(find /path/to/dir -type f); do tr -d '\r' <$file >temp.$$ && mv temp.$$ $file; done

# Canonical for each loop bash shell array [@] quotes array elements.  Arrays need not be decalared.
funcarr=(DPGeneral Valtrex); for f in ${funcarr[@]}; do $f; done

# Determine Windows Box uptime:
$ sz=$(systeminfo /U uxx19043 /P uxx06te /S '\\rtpsawn31'|grep 'Up Time'|awk '{print $4}')

# Cygwin
$ systeminfo /U uxx40032 /P uxx06pr /S rtpsawn332

# Prepend 'vi' to beginning of line:
$ locate --ignore-case --database=/var/lib/locatedb.code foo|sed 's/^/vi /'

if [ -d '\\rtpdscel01dm06\rsh86800$' ];then echo 'directory exists'; fi

# bash only
diff <(sort file1) <(sort file2)

# For loop shell array
for x in "${MAPFILES[@]}"; do ... done

# Canonical backup quick tar quick backup
tar cvfz /cygdrive/u/bkup/sd.`date +%d%b%y`.tgz CODE/

# Comma delimited items split into lines, one item per line (convert wide to long)
awk -F, '{ print $1; print $2; print $3 }' t.csv

# Count unique batches, in column 1, from CSV file
tail +2 "/home/bheckel/projects/datapost/tmp/VALTREX_Caplets/OUTPUT_COMPILED_DATA/CSV valtrex_FreeWeigh.csv"|cut -d ',' -f1|sort|uniq|wc -l

# Temporary mount:
$ mount -f "C:\Users\bheckel_6\Documents\My Dropbox\Public\USB\cygwin\home\bheckel" /home/bheckel  # temporary
$ mount -m  # cat the current mountpoints for pasting into /etc/fstab for permanent mount

# Is database up?
while true; do date;sqlplus -S sasreport/sasreport@usprd259 @donothing; echo 'ok';date;echo;sleep 300; done;
# Poor man's progress bar timer - how long does it take to connect to database:
i=0;x=0;y=0;while true; do x=`date +%s`;sqlplus -S sasreport/sasreport@usprd259 @donothing; y=`date +%s`;for i in expr $y - $x; do echo -n '.'; done; echo;sleep 300; done;

# Passed-in shell variable $1 starts with a dash
... elif [ "${1:0:1}" = '-' ];then ...

# Iterate shell array list of filenames (bash only?)
dotfiles=( .bashrc .vimrc ); for f in ${dotfiles[@]}; do echo $f; done

ssh rtpsh005 ps -ef | grep lms_client*|wc -l  # count LIMS users

# Print HPUX
lpr -dprinter_name file_name

# Determine day of week
if [ `date +%a` != Mon ];then ...

# Cygwin w3m
find . -name "*.dll" -or -name "*.exe" | xargs -r strip

# Using awk tilde find the process with 'ba' in its name in column 8:
#     1072    4384    1072       4948    0 1003   Feb  1 /usr/bin/bash
ps | awk '$8 ~ /ba/' -

~/bin/vscp 'rsh86800@rtpsh005:/opt/QCServer/A.05.00/svr/files/Inspec_Results-0211.log'

# Choose a random line from a file (bash)
F=dhammapada.txt;TOTLINES=`wc -l $F|awk '{print $1}'`;LINENUM=$[($RANDOM%${TOTLINES})+1]; sed -n "$LINENUM"p $F

# bash ls skip do not show .orig files.  TODO not sure how robust this is - may need  $ find . -not -name '*orig'
ls tzu!(.orig)

# Canonical bash function definitions
myfunction () { ... }
function myfunction { ... }

urxvt-X.exe -display -bc -e /bin/bash --login

# Create empty directories and subdirs (skip files):
cd ~/projects/datapost/data
TMPD=/home/rsh86800/tmp/11Apr11_1302538066/datapost/data; mkdir -p $TMPD && find * -type d | while read d; do mkdir ${TMPD}/${d}; done

30 09,15,20 * * * grep http /home/chronos/user/Bookmarks | awk '{print $2}'| sed 's/"//g' | sed 's/$/<BR>/' >| /home/chronos/user/Dropbox/Public/Equanimity/bm.html 2>|/home/chronos/user/cron.log

# bash calculator:
echo $[(5*3)-2]

# For Windows users who don't have tar and gzip:
find . -name '*png' |xargs zip 
# Junk the dirs, all files go in single zip (make sure don't have dup filenames in subdirs)
find . -name '*png' |xargs zip -j 

xxUNIXxx END:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:

xxCxx START:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-: {{{1

/* Zero out a high order bit (used to display negative, parity, etc.).
 * AND'ing with 0111 1111 leaves all bits but the first one
 * untouched.
ch = ch & 127;

/* Turn on ECHO by using an OR */
flags |= ECHO;
/* Turn off ECHO by using an AND and an invert */
flags &= ~ECHO;

Any bit AND'ed with a 0 yields a 0.
Any bit OR'ed with a 0 yields itself.

/*  If variable ptrX "holds the ADDRESS of a MEMORY LOCATION containing an
 *  int", what it really means is that variable ptrX holds the ADDRESS of the
 *  first byte of the memory used for the int being pointed to.  That is one
 *  reason why variable ptrX, acting as a pointer, must point to a specific
 *  type.  The system needs to know HOW MANY bytes to handle as part of the
 *  data being pointed to. 

/* Increment p, the POINTER.  * binds less tightly than ++  
 * Same as *(p++) 

/* Increment the VALUE pointed to by p, the pointer.
 * Force * to bind more tightly than ++ 
/* Normally *p++ is the same as *(p++), above forces it otherwise. */

/* Same--the contents of the object i locations past the one pointed to by p 
 * They're equivalent and valid if either p is a pointer or if it is an array.
*(p+i)   /* pointer arithmetic */

/* Iterate over a string approach 1 -- array */
for ( i=0; str[i]!='\0'; i++ ) { puts(str[i]); }

/* Iterate over a string approach 2 -- pointer */
while ( *str != '\0' ) { puts(*str++); }

/* Iterate over a string approach 3 -- terse pointer */
while ( *str ) { puts(*str++); }

// Go to the end of a string (e.g. to allow concatenation, etc.)
while ( *str ) str++;

/* Declare pointer to constant int, which means that although the pointer
 * can be modified (to point to different locations), the location pointed to
 * (that is, *pci1) can not be modified. 
 * It can be used to document (and enforce) a pointer parameter which a
 * function promises not to use to modify the location in the caller. 
const int *pci1;        /* or int const *pci1 */

/* Declares a pointer-to-int which cannot be modified (it cannot be set to
 * point anywhere else), although the value it points to (*pci2) can be
 * modified. 
int * const pci2;

/* Copy the value pointed to by p2 to the value pointed to by p1 ... */
*p1 = *p2
/* ... compare with setting p1 to point wherever p2 points. */
p1 = p2

If you have a pointer named ptr that has been initialized to point to the
variable var, the following are true:
 1.  *ptr and var both refer to the CONTENTS of var (that is, whatever value
     the program has stored there). 
 2.  ptr and &var refer to the ADDRESS of var. 

int x[] and int *x both mean "pointer to int" 

/* Use line number as informative exit code (view via shell's $?). */

// Legitimate floating-point constant values are: 1e4 (exponent), 1.0001,
// 47.0, 0.0, and -1.159e-77. 

// Initialize array to zeros.  Compiler will use the first initializer for the
// first array element, and then use zero for all the elements without
// initializers (may be more efficient than using a for loop).
int arr[6] = {0};

// Size of an array idiom.  does the trick in a way that doesn't need to be
// changed if the array size changes.  Size of entire array divided by the
// size of 1st element.
int n = sizeof a / sizeof *a;
// or
int n = sizeof a / sizeof a[0];   
// or
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

// Definition  - the place where the variable is created or assigned storage.
// Declaration - the placeS where the nature of the variable is stated but no storage is allocated.

// Must allocate space before copying source string to destination.  This
// assumes that you don't preallocate dest this way:  char dest[80];
char *dest;
dest = (char *)malloc(strlen(source) +1);
strcpy(dest, source);   /* ok now */

/* Safe error trap for malloc which itself requires *some* memory on failure */
#define MALLOC(x,y) do { y malloc(x); if (!y) abort(1); } while(0)

/* Pointers to structs. */
/* eliminates the need for the ugly */
/* In both cases, we are evaluating the element title of the structure pointed
 * to by ptr_mystruct 
/* Pointers to structs summary: */
// Element 'title' of structure 'ptr_movies'   
// Element 'title' of structure pointed to by 'movies'
movies->title   // same as the ugly (*movies).title 
// Value pointed to by element 'title' of structure 'movies'
*movies.title   // same as the ugly *(movies.title) 

You can find out what shared libraries a program requires by using ldd (List
Dynamic Dependencies) 
$ ldd /usr/bin/lynx

External (global) variables initialize to 0. Local variables init to garbage.

// Minimum C macro
#define MIN(x,y) ((x) <= (y) ? (x) : (y))

// Compare two strings:
char *name = "Choice 1";
if ( strcmp(name, "Choice 1") == 0 ) {
  // You've found a match

// Super debugger.  Looks like this: DEBUG: ascii.c, 51, Jul  9 2002, 15:04:43
printf("\nDEBUG: %s, %d, %s, %s\n", __FILE__, __LINE__, __DATE__, __TIME__);

// const member function:
void show() const;   // promises not to change invoking object

// Determine if odd number:
int odd = (fmid - bmid) & 1;

// Assuming a struct named Point exists, use this to simplify typing:
typedef struct Point Point;

// Ragged array of ptrs to null terminated strings.
char* mystrings[] = {"how", "now", "brown", "cow"};

// Comment out a section of code (will skip main()):
#ifdef BOBHDEBUG;  main(); #endif

// Good declaration of an array (assumes  #define MAXSTRINGLEN 42  earlier):
char array[MAXSTRINGLEN+1] = { 0 };

Compile a Cygwin app that doesn't depend on cygwin1.dll
$ gcc -mno-cygwin 99bottles.c

xxCxx END:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:

xxSASxx START:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-: {{{1

V8 SAS online docs  onlinedoc documentation manual help webpages:
V9.1 SAS online docs

Missing value '.' always sort lower than char or num and ._ sorts lowest of all
SAS Special Missing Value (.A thru .Z)
...else if comment = 'refused to answer' then age = .A;...

 /* Write all variables to the Log with "foo=" notation on one line: */
put _ALL_  /* print PDV to Log */
put 'WARNING: ' _ALL_
 /* Write all variables to the Log with "foo=" notation on one line per var: */
put (_ALL_)(=)
 /* Use anywhere but can't combine to one %put */
%put !!!; %put _USER_;

 /* Macro -- no quotes! */
%put You find yourself in a maze of %upcase(twisty SAS passages) all alike;
 /* In a DATA step -- quotes, no commas */
put 'fname is ' fname=;
put '!!!' _ALL_;

 /* Writes specific variables to the Log.  NO COMMAS. */
put varname1= varname2=;
 /* Automatic concatenation: */   
put 'here it is: ' varname1=;
 /* Carriage return in output: */
put '13'x;  /* s/b the same */
 /* Alternative is to use a blank  title2;  */

Runaway GUI SAS killer:
*'; *"; */; %mend; run;

 /* Free up space - delete datasets */
proc datasets library=WORK; kill; QUIT;  /* !not RUN; */
proc datasets NOlist; delete FooDS BarDS; quit;

Column input with some missing data -- use truncover
List input with some missing data at the rightmost edge -- use missover to keep SAS from trying, stupidly in most cases, the next line

 /* Describe paths to SAS libraries: */
libname _ALL_ list;

 /* Clear libnames */
libname _ALL_ clear;  or  libname L clear <---only one libname allowed!

 /* Determine where the WORK temp library is located on your system: */
libname WORK list;
 /* or */
%let workpath=%sysfunc(pathname(work));

SAS debugger e.g. data foo / DEBUG; ...

'07jul00'D              <---SAS date constant
'07JUL2000'D            <---SAS date constant
'04:15'T                <---SAS time constant (seconds since midnight 0-86400)
'04:15:66pm'T           <---SAS time constant (seconds since midnight 0-86400)
'07jul2000:04:15:00'DT  <---SAS datetime constant

SAS Functions work *within* an observation.  Procedures work *across* observations.

 /* Increment in macro.  Like yr++ */
%let YR1 = 2002;  %let YR2 = %eval(&YR1+1);
 /* Convert macrovariable from string to numeric (integer): */
%let Y = 2000; %let YR = %eval(&Y+0);
 /* Convert macrovariable (always string) to numeric: */
data _null_; age=input(symget('age'),12.); run;

 /* SAS X command (ok in open code): */
x 'c:/util/vim/vim61/gvim.exe -c "set winsize=100 20" out.dat';

 /* Canonical generate random number between 1 and 5 */
randomnum = ceil(ranuni(0) * 5);
 /* Generate random number between 100 and 123: */
randomnum = 23*ranuni(-1) + 100;

 /* Adjust the line length (if not using JCL): */
file OUTF LRECL=1048576 PAD;  /* mainframe max?? */
file WSIP21C LRECL=32767;  /* Windows max */

Interactive SAS on OS/390 (from TSO command line):
==> sas options('dms')
==> sas options('dms yearcutoff=1905')

Using 1920 default: 00...19 becomes 2000...2019

//* Use your own SAS System Options in JCL:
//          OPTIONS='MEMSIZE=0'                                

 /* Actually sets the auto variable myfname, not the keyword FILENAME, to
  * the physical name of the currently opened file.  Cowabunga! 
infile IN FILENAME=myfname;

 /* SAS hexadecimal tab */
'09'x  or  '05'x  or  '3132,3334'x
put aprclass '09'x '09'x APR_Count;

 /* It's an alphabetical character isalpha: */
if ship GE 'a' and ship LE 'z' then delete;
 /* It's a numeric character isnum: */
if indx GE '0' and indx LE '9' then delete;
 /* Keep only numbers from a mixed var (CHAR formatted).  See */
isnum = verify(result, '.0123456789'); ... if isnum eq 0 then put "pure numerical";

 /* ltrim() and rtrim() don't exist in SAS */

 /* Distributive range input statement: */
input @166 (r1-r15) ($CHAR1.);
input @166 (c1-c15) (:$1.);

 /* Super input statement uses the data! to determine column position */
input @'IP Address' n1 n2 n3 n4 3.;

 /* Move cursor one to the left, backspace, to squeeze colon against word: */
put @1 myname +(-1)":"  @30 myvalue;

 /* Multiple datasets on the set statement: */
data work.all; set %do j=1 %to 3; work.tmp&j %end; ; run;

 /* Get current year date. */
call symput("CYR4", substr(put("&sysdate9"d,mmddyy10.),7,4));

 /* Increment the symput generated mvar */
call symput('RUNME'||compress(put(_N_,5.)), executemacro);

 /* Equal colon -- same as using LIKE 'mormer%' in SQL. */
if foo =: 'mormer';

 /* Use more than one library, look in best first, then justok if not found: */
libname mylib (best justok);
 /* libname concatenation. Works on z/OS too. Only a WARNING: for idontexist/ */
libname CONCAT ('c:/temp' 'c:/cygwin/tmp/' 'c:/idontexist');

 /* Uppercase a macrovariable: */
%let the_type=%upcase(&the_type);

 /* Mainframe filename */

 /* Fixed length file.  Pads to 70. */
filename f 'c:/temp/foo1' lrecl=70 recfm=f;
 /* Variable length file.  No padding. */
filename f 'c:/temp/foo2' lrecl=70 recfm=v;

 /* Today's SAS epoch (range is 1582 - 20000 AD) date. Convert unix to SAS epoch date */
$ date +%s |awk '{d=int($1/86400+3653)} END {print d}'

 /* Left zero pad a number: */
zerocert=put(certificate, Z6.);

 /* Sum accumulator is auto-retained (but  foo = foo + 1  is not) */

 /* Reorder the variables in a dataset (alternatively use proc report): */
retain first second third;

 /* Create a C-like null terminated string: */
substr(mystr, mylen+1) = '00'x

 /* Name of currently running SAS program file: (like $0 in shell): */

 /* Class variables:  nums (discrete categories) or chars, identify classes
  * or discrete categories on which calculations are done.  E.g. gender,
  * country, state, zip
  * Analysis variables:  numbers, usually continuous, appropriate for
  * calculating averages, sums, etc.  E.g. salary, number of orders

 /* Pick off the MORMER1 suffix, and ignoring trailing, trash returns "MOR" */
%let FN=BF19.FIX0342.MORMER1;
%let EVT=%substr(%scan(&FN, 3, '.'), 1, 3);

 /* SAS exponentiation */
x = 2**3;

 /* Syntax check program (compile) without running or overwriting files (for debugging): */
options obs=0 NOreplace;
 /* Syntax check datastep (compile) without running or overwriting files (for debugging): */
run cancel;

 /* Do to first obs: */
if _N_ eq 1 then put 'data step has BEGUN EXECUTING once';
 /* Do to last obs: */
set l.sumventolin01a (obs=10) end=e; if e then put 'footer';
 /* Caution: _N_ is only counting begun iterations of the implied loop of the dataset, NOT the observations.  */

Subsetting IFs can appear only in DATA steps but WHERE statements can appear in DATA or PROC steps.

 /* Run SAS without my ~/bin/sasrun */
$ sas -sysin; cat t.log
$ sas -sysin; vim -o -c '/^ERROR.*:\|^WARNING:/' t.log t.lst
" Run a .sas from Vim on an alien box
:!/cygdrive/c/Program\ Files\/SAS\ Instititute/SAS/V8/sas.exe -sysin %
:!/cygdrive/c/Program\ Files\/SAS\ Instititute/SAS/V8/sas.exe -sysin % -altlog %.log -altprint %.lst

 /* Run Version 9 V9 SAS from commandline */
c:/PROGRA~1/SAS/SASFoundation/9.2/sas.exe -sysin && vi *.l??

 /* Run Windows PC SAS from command line (often need an ENDSAS; if run via .bat) */
$ c:/PROGRA~1/SASINS~1/SAS/V8/sas.exe -sysin -altlog t.log -altprint t.lst
$ /cygdrive/c/Program\ Files/SAS\ Institute/SAS/V8/sas.exe -sysin && vi -c 'map q :q!<CR>' t.log
$ c:/PROGRA~1/SAS/SASFoundation/9.2/sas.exe -sysin && vi *.l??
 /* same */
$ c:/Program\ Files/SAS\ Institute/SAS/V8/sas.exe -sysin -log t.log -print t.lst
 /* String foo is available in &SYSPARM */
$ c:/PROGRA~1/SASINS~1/SAS/V8/sas.exe -nosplash -sysin -altlog Apr.log -sysparm foo
 /* Passing a comma separated list will require e.g.
  * %let samplist=%scan(%bquote(&SYSPARM), 2, '_'); 
  * in the code:
$ date;c:/PROGRA~1/SASINS~1/SAS/V8/sas.exe -sysin -altlog 01.log -sysparm 01_231973,231591,231476
 /* Run Solaris Unix SAS from command line */
sas -sysin; cat t.log; cat t.lst
 /* If you can't edit the command line, use these in start/end of the code to save Log and List (NEW to avoid append): */
proc printto LOG="D:\foo.log" NEW PRINT="D:\foo.lst" NEW; run; ...code... proc printto;run;
 /* Keep GUI open during the run.  Instead of -sysin */
c:/PROGRA~1/SASINS~1/SAS/V8/sas.exe -autoexec "\\rtpsawnv0312\pucc\Serevent_Diskus\CODE\" -sysparm "\\rtpsawnv0312\pucc\Serevent_Diskus\CODE"

# Cygwin
$ echo 'proc print;run;' >|; c:/PROGRA~1/SASINS~1/SAS/V8/sas.exe -sysin
echo "options ps=max;libname l '//Rtpdsntp032/DataPostArchive/Ventolin_HFA/OUTPUT_COMPILED_DATA';proc freq data=l.ven60_analytical_individuals;table mfg_batch test;run;" >| u:/tmp/ && c:/PROGRA~1/SASINS~1/SAS/V8/sas.exe -sysin 'u:\tmp\' -log 'u:\tmp\t.log' -print 'u:\tmp\t.lst'; cat 'u:\tmp\t.lst'

 /* Describe option settings in effect: (also sr ~/code/sas/ linesize) */
proc options option=&SYSPARM define value; run;

format vs informat: Formats modify the external representation of a value (preexisting in a ds).  Informats convert raw data into SAS representations (to be put in a ds).

 /* Current dataset macrovariable formatted to "LIBRARY  DSNAME" */

 /* Print quotes around a variable, in this case, myvar */
put "!!! found " myvar $QUOTE.;

 /* Check if a file has a SAS extension */
if index(upcase(file),'.sas') > 0;  /* true */

 /* Portability -- Use this JCL for SAS filename on MF: */
 /* vs. this JCL-less method on the PC via Connect: */
filename IN 'BF19.MOX0401.NATMER' DISP=SHR;

 /* Include code plus display source w/o an options statment (%include is synchronous): */
%include '' / SOURCE2;

 /* Paste code between these two */
%include "&HOME/code/sas/";
options NOmlogic NOmprint NOsgen;%Tabdelim(WORK.tmp, 'junk.xls');

 /* Find max using a SAS range: */
retain hi; hi=max(hi, DatastepVarWeWantMaxFrom);
 /* Find max using a SAS range: */
if max(of one1-one3) < 5 then ...

 /* Test for oddness */
mod(x,2) eq 1
 /* Test for eveness */
mod(x,2) eq 0

 /* SAS array declare and initialize */
array starr{*} $2 st1-st57 ('AL', 'AK', 'AR', 'AZ', 'CA', 'CO');
 /* SAS array access */
do i=1 to dim(starr); otherarr{i} = starr{i}; end;

 /* Get the $HOME environment variable (Windows & Unix at least) */
%let myhome=%sysget(HOME);
 /* Determine %SASROOT% */
%put %sysget(SASROOT);

 /* Substring */
%put %substr(2168, 3, 2);
data _null_; x=substr('2168', 3, 2); put x=; run;

 /* Good demo sample template dataset: */
proc print (obs=10); var region stores sales returns; run;
data tmp; set; if region in:('A', 'E'); run;

proc print data=MVDS1.caNEW; where acme_uc eq: 'Y'; run;
proc print LABEL SPLIT='*' NOOBS N;

 /* Macro with parameters parms: */
%macro Foo(bar, baz); %put &bar and &baz; %mend; %Foo(test ing, me);

 /* Avoid having SAS eliminate leading whitespace (as would $2.) */
input foo $CHAR2.;

 /* Suppress any input errors in SAS Log and keep _ERROR_=0 */
input name $8.  number  ??;

 /* Macro date - format today's date into a macrovar: */
%let FDATE=%sysfunc(date(), YYMMDD10.);
%let FDOLLARS=%sysfunc(putn(&MYNUM, DOLLAR10.));

 /* Operating system specific option: */
%macro OS; %if &SYSSCP eq OS %then %str(options NOs99nomig;); %mend; %OS

 /* Thin out cleanout SAS Log, can use \| to get >1 line at a time */
:g/\s*SYMB\|\s*MLOG\|\d\+\s*THE SAS/d

 /* Best small 10% random sample sampling: */
data OUT.WANEW; set IN.WANEW; if uniform(0) le .01; run;

 /* Don't add lines with NULLs */
if sex = '00'x||'00'x||'00'x then delete;

 /* Most efficient block size on mainframe: Moderate to large DASD-stored datasets s/b blocked at half a track. Small ds and catalogs s/b blocked at 6144 bytes. Tape 32760 bytes. */
options blksize(dasd)=half;

 /* Perl regex in SAS */
data; set; if _N_ eq 1 then rc=prxparse("/ica$/"); retain rc; if prxmatch(rc,region); run;

 /* v9+ only I think */
%if not %index(&endyr, 20) %then %abort;
 /* so use this (also aborts ok inside a macro): */
data _NULL_; abort abend 008; run;

 /* macro in() for macro */
%if %sysfunc(indexw(AK AR VI WV, &STATE)) %then %do; %put is in list; %end;
 /* macro not in for macro multiple values */
%if not %sysfunc(indexw(&RANGEVARS, &VAR)) %then %do; %put is NOT in list; %end;

 /* Remove trailing dot */
myvar = trim(translate(myvar, '', '.'));

 /* Simple datetime stamp: */
%put %sysfunc(putn(%sysfunc(datetime()),DATETIME.));

 /* Print timestamp at end of job */
%put ended %sysfunc(putn(%sysfunc(datetime()),DATETIME.));

 /* Time a job */
%let _start=%sysfunc(time()); %put NOTE: %sysfunc(getoption(SYSIN)) started: %sysfunc(putn(%sysfunc(datetime()),DATETIME.));
%put NOTE: SYSCC: &SYSCC (%sysfunc(getoption(SYSIN)) ended: %sysfunc(putn(%sysfunc(datetime()),DATETIME.)) / minutes elapsed: %sysevalf((%sysfunc(time())-&_start)/60));

 /* Quick sample dummy dataset */
data x; do i=1 to 5; do j=20 to 25; do k=100 to 101; output; end; end; end; run;

 /* Create an empty dataset */
data work.empty; set work.sample (obs=0); run;
data reallyempty_1obs_0vars; run;

 /* Search SUGI papers via Google w/o that ugly lexjansen page */
findmystring filetype:pdf

 /* BETWEEN statement is inclusive /*
where i between 1 and 5;

 /* Same */
options pagesize=32767;
options pagesize=max;

 /* Comma separated, single quoted mvar SELECT...INTO :foo list in proc sql: */
select quote(trim(mycharvar)) into :RISKVARS separated by ', '
select froms, tos, dist into :ITEM1, :ITEM2, :ITEM3

 /* If you use this: */
 /* you also need this: */

 /* Find and use custom format aerodtt. in c:/datapost/code/formats.sas7bcat */
options fmtsearch=(MYFMTLIB); libname MYFMTLIB 'c:/datapost/code';

 /* Calculate seconds since the SAS epoch */
data _null_; when=datetime(); put when=; run;

 /* Get last highest -1th element of string */
if substr(reverse(trim(revising_status)),1,1) eq 'N' ...

x='8ZM1234'; if substr(x, 2, 1) eq 'Z' then ...

 /* Remove the last five chars of a mvar */
%let str=%sysfunc(reverse(%substr(%sysfunc(reverse(&str)),5)));

cat "//''" | vi -     # HFS

 /* Remove trailing comma: */
%let YRCNTS=%substr(%bquote(&YRCNTS), 1, %length(&YRCNTS)-1);

 /* Count observations count without opening dataset (or if it's open in SAS GUI) */
data _null_; rc=attrn(open('tmp1.pull_lift'), 'NOBS'); put rc=;run;
%macro m; %put %sysfunc(attrn(%sysfunc(open(tmp1.pull_lift)), NLOBSF)); %mend;%m
...%if %sysfunc(attrn(%sysfunc(open(_LAST_)), NLOBSF)) lt 100 %then %do; %put ok; %end;...

 /* Count observations without opening dataset IF GOING TO USE DS LATER */
%let dsid=%sysfunc(open(; %let cnt=%sysfunc(attrn(&dsid, NOBS)); %let rc=%sysfunc(close(&dsid));
%let dsid=%sysfunc(open(; %let cnt=%sysfunc(attrn(&dsid, NVARS));
data _null_; dsid=open('work.tmp'); numobs=attrn(dsid, 'nobs'); rc=close(dsid); run;

 /* Count observations */
data _null_; if 0 then set nobs=count; call symput('CNTOFOBS', count); stop; run;

 /* Count observations */
proc sql; select count(*) into :CNTOFOBS from; quit; 

 /* Day of week number 1=Sunday 7=Saturday */
if weekday(today()) eq 2 then put "it's Monday";
 /* Conditionally run macro if it's Wednesday */
data _null_; if weekday(today()) eq 4 then do; call execute('%include "&CODE\PLOT_CODE\";'); end; run;

str2 = '%include "' || left(trim(product)) || '\' || left(trim(product)) || '.sas"';
call execute(str2);
str1 = '%mymacro(' || left(trim(product)) || ',' || left(trim(server)) || ',' || left(trim(writeoutput)) || ');' ;
call execute(str1);

 /* Canonical convert datetime to human */
data _null_; human=put(1613578239, DATETIME18.); put human=; run;

 /* Convert DATETIME to DATE */
mysasdate = datepart(mysasdatetime);
 /* Convert DATE to DATETIME */
mysasdatetime = dhms(mysasdate, 0, 0, mysastime);
mysasdatetime = mysasdate*86400  /* seconds in a day */

data _null_; myquarter =        floor((mymonthnumber-1)/3)+1; put mycurrentquarter=; run;
data _null_; mycurrentquarter = floor((month(date())-1)/3)+1; put mycurrentquarter=; run;

 /* Avoid missing failure if datetime inputs are incomplete */
mydttm = dhms(mydate, max(0,hour(mytime)), max(0,minute(mytime)), max(0,second(mytime)));

 /* Convert datetime floating point number to human 25AUG2005 date */
%put %sysfunc(putn(1440588139.7, datetime9.));
%put %sysfunc(putn(1441637788, datetime14.));

 /* Check for success to this point before continuing to destructive section */
%if &SYSERR eq 0 %then %do ... %end

 /* Speed up proc sql delete v9+ */
libname SAND ... direct_exe=delete ...;

 /* Speed up proc append to database */
libname SAND ... bulkload=yes ...;

 /* Count number of characters in a string v9+ */
commas=countc(myvar, ',');

 /* Colon input specifier - we'll take anything between the delimiters but with a max of 40 chars: */
input ProviderLicenseNumber :$40.;  /* no preceeding LENGTH statement needed */

 /* Capture part of a string */
captureUpToDash = substr(SampName,1,index(SampName, '-')-1);
 /* Better */
captureUpToDash2 = scan(SampName,1,'-');  /* be explicit on 2nd parm or it'll use default of split on  spaces . < ( + & ! $ * ) ; ^ - / , % | */

Same but handle spaces differently

 /* View all formats */
proc format library=work FMTLIB; run;

 /* diff two datasets */
proc compare BASE=l.dsold COMPARE=l.dsnew; run;

SELECT COUNT(DISTINCT samp_id)  /* good */
SELECT DISTINCT COUNT(samp_id)  /* bad - syntax is ok but probably not what you want */

 /* Cannot use to rename a ds in same lib */
proc copy in=OLDLIB out=NEWLIB memtype=data; select myds1 myds2...; run;
 /* so use this instead of proc copy */
proc append base=newdstocreate data=olddsname FORCE; run;
 /* True append */
proc append base=ci_oth data=ci_oth_&strength; run;

 /* format= relies on e.g. ls=N cannot have ls=max to pull this off */
options ls=80; proc sql; select specname FORMAT=$20. from v ; quit;

proc sql; select id, (dis-adm)+1 AS mycalc LENGTH=4 LABEL='foo' from bar; quit;

libname ORA oracle user=pks password=pks path=usdev100 schema=pks;

 /* Fast freq */
proc freq like 'A%')); run;
proc freq data=l.lelimsindres01a201962(where=(specname like '%2064%')); table specname*varname; run;
proc freq; table description*market / LIST nocum norow nocol nopct; run;

 /* Where IntrNet keeps its datasets for a session */
%let spath=%sysfunc(pathname(SAVE));

 /* Canonical IntrNet URL */

 /* Display SAS Intrnet ENVIRONMENT */

 /* Wake up, ping restarted IntrNet server */

 /* SAS' version of Oracle's ROWNUM<5 */
where monotonic() < 5

 /* E.g. C:\cygwin\home\bheckel\tmp\testing\ */
%put fully qual name of the currently running pgm: %sysfunc(getoption(SYSIN));
%put basename only of currently running pgm: &SYSPROCESSNAME

 /* Determine OS platform */
%put !!!&SYSSCP;

 /* View all macrovariable data (GLOBAL, etc) */
data vars; set SASHELP.vmacro; run; proc print data=_LAST_(obs=max); run;

 /* View created dataset */
options noxwait;x "start lelimssumres01a&nm..sas7bdat";

 /* Auto-vivifies any var not read in (or worse, typo'd) */
format matl_typ $18. batch_nbr $10.;

 /* Note: not 'lastobs'     ___    */
set work.sample (firstobs=2 obs=5);

 /* Same as SAS sort-sort-merge.  Emulate a SAS merge without having to sort. */
proc sql; select coalesce(one.acct, two.acct) as a, rate, balance from one FULL JOIN two  ON one.acct=two.acct ; quit;

data _null_; do while ( x<3 ); put x=; x+1; end; run;
%macro w; %let i=0; %do %while ( &i lt 3 ); %put &i; %let i=%eval(&i+1); %end; %mend; %w
... do year=1990 to 2004 while ( capital > -1 ); ...
... %do i=1 %to 4 %by 2; %put &minyr.&i; %end; ...  /* only 2 puts */

 /* run d:\sas_programs\ on blade server: */

 /* Prepare single quoted date for Oracle TODO not correct */
data _NULL_; call symput('STARTDT', "'"||put("&SYSDATE9"D-1, DATE9.)||"'"); run;

 /* NODUP eliminates obs that are exactly the same across ALL variables.  NODUPKEY eliminates obs that are exactly the same across *only* the BY variables. */
proc sort data=foo out=bar NODUPKEY;

 /* proc sort alternative */
proc sql;CREATE INDEX MYSORTEDx ON lelimsgist05e (Samp_Id, Indvl_Meth_Stage_Nm);quit;

dm 'clear log; clear lst; wpgm'; 


LENGTH TimeNum 8 Meth_Peak $3 Indvl_Tst_Rslt_Val_Char $40;

 /* Specific number of random records from a dataset: */
proc surveyselect n=10 data=tmp out=foo; run;
data r; do i=1 to 10; obsnumiwant=ranuni(int(datetime())); set d; output; end; stop; run;

attrib state length=$3 label='foo bar' format=$40.; 

 /* Foreach dataset in library, push names into a mvar: */
proc sql NOPRINT; select memname into :DSETS separated by ' ' from dictionary.members where libname like 'WORK'; quit;
options ls=180 NOlabel;proc sql;select * from dictionary.columns where libname eq 'WORK' and memname eq 'EFORMSNUMCH';quit;

 /* Complex oracle SEPARATED BY */
select distinct r.sampid, s.specname, put(r.sampid,F6.)||'-'||s.specname into :RETESTSAMPIDS separated by ',', :METHS separated by ' ', :METHPAIRS separated by ' '

%if %sysfunc(fileexist(&fn)) %then %put exists; %else %put no;

" Convert SAS input to put statments:
" e.g. 
"   no_obst $ 125  amnio $ 126  elec_fet $ 127-128  ind_lab $ 129
" becomes 
"   @125 no_obst  @126 amnio  @127 elec_fet  @129 ind_lab
:s:\(\w\+\) \$ \(\d\+-*\d\+\):@\2 \1:gc

/* Setup the default SAS System user work folder and autocall in 
 * /cygdrive/c/Program\ * Files/SAS\ Institute/SAS/V8/SASV8.CFG
-WORK "E:\SAS Temporary Files\"
-SET SASAUTOS  ( "d:\Auto_Call" ...

 /* Do not auto-delete, save WORK datasets and _TD.... in 'SAS Temporary Files' dir after run completes. Override default. */
options NOworkterm; %put !!! WORK lib is:; libname WORK list;

 /* Keep temporary WORK datasets in your own dir, not in the default _TD....\ */
libname W './workdir'; options USER=W;  /* workdir must already exist! */

 /* Use datasets in pwd (w/o libname prefix "L") pretending that's WORK: */
options USER=L;

/* Single quote in SAS macro requires quoting with percent sign % */
%put this is %str(John%'s office) here;

 /* Read only do not modify dataset */
options NOreplace;
 /* Read only do not modify anything in library */
libname L 'U:\courses\PRG1\PRG1 course data' access=READONLY;

 /* Redirect from LOG device to PRINT device to draw line in the .lst (tilde repeats 78 times) */
data _null_; file PRINT; put 78 * '~'; run;

%local i j item;  /* no commas */

 /* Comma-separated SQL macrovariable */
select distinct quote(trim(batch_nbr)), quote(trim(matl_nbr)) into :batches, :materials separated by ','
 /* But for oracle we need single not double quotes (then add a leading & trailing quote): */
%let sq=%str(%'); %let batches=&sq&batches&sq; ...
select batch_nbr, matl_nbr into :batches separated by "','", :materials separated by "','"
select distinct region into :region1 thru :region3 ...

x "move /Y lelimssumres01a.sas7bdat \\rtpsawn321\d\sql_loader\LeLimsSumres01a&suffix..sas7bdat";

 /* Tells SAS not to worry about keeping obs with the same BY variable values in the same order (for speed) */
proc sql NOEQUAL ...

 /* DELETE returns to the top of the datastep w/o writing.
  * RETURN returns to the top of the datastep with a default OUTPUT.
  * LEAVE exits a loop.
  * CONTINUE goes to the next iteration of the loop.

 /* PUT STATEMENT writes to a buffer (default: LOG) vs. INPUT statement reads from a buffer (default: CARDS)
  * FORMAT specify how data is to be written vs. INFORMAT specify how data is to be read
  * FUNCTION:  put(SAS data, $formats.)  vs.  input(raw data, $informats.)

 /* concatenate (stack) two datasets */
... set x1 x2; ...
 /* interleave two datasets same except end up sorted */
... set x1 x2;  by state; ...

grandtot = sum(of idnum--qtr4);

m=mean(of a[*]);   /* variable array */
m=mean(of v1-v5);  /* variable list */

 /* Split parse string on dash taking 7ZP6699 from 7ZP6699-4148428 */

 /* Get every 4th obs */
if mod(_N_, 4) eq 0; ...
 /* Get every other obs */
if mod(_N_, 2) eq 0; ...

 /* Determine where WORK dir is located: */
data x; x=1; output; run; proc contents; run;
 /* Better */
proc contents data=WORK._ALL_; run;
proc contents data=WORK._all_ NODS; run;  /* cleaner, ds names only */
proc contents data=L._ALL_ out=WORK.prcnts; run;

 /* List all vars in dataset: */
proc sql;select name from dictionary.columns where libname eq 'L' and memname eq 'LELIMSINDRES01A210255';quit;

 /* Canonical do loop: */
%do i=1 %to 5; %put here is &i; %end;
%do i=5 %to 1 %by -1; %put here is &i; %end;
 /* Canonical do loop list: */
data _null_; do i = 1, 2, 3; put i=; end; run;
do i = 1, 2, 3, 'a', 'b', 'c';
do i=1 to 3, 'cat', 20; ...; end;

 /* Canonical do loop until: */
do until (n>100); ...
do i=1 to 10 until (n>5); ...

do while (1);  /* infinite loop */

 /* Has zero observations?: */
  /* If don't care about closing, otherwise need to get a ds id number */
data _null_; numobs=attrn(open('work.tmp'), 'nobs'); put "!!!" numobs=; run;
...%let dsid=%sysfunc(open(CI_release)); %let cnt=%sysfunc(attrn(&dsid, NOBS)); %let rc=%sysfunc(close(&dsid)); %if &cnt eq 0 %then %do; %goto EXIT; %end;...

 /* Build tail of filename c:/foo/tmp/bar.txt */
%let PRODUCTNAME=%substr(&DIRROOT, %eval(%index(&DIRROOT, tmp)+4));

 /* %global is distributive */
%global foo bar;

 /* Skip first observation, get 2 3 4 5 only */
set work.sample (firstobs=2 obs= 5);

if description ne: 'al' then do; file "&DIRROOT\&SYSMACRONAME._Error.txt"; put "UNEXPECTED: &SYSDATE &SYSTIME " description=; end;

 /* Maximum storage size of SAS numeric using default 8. */

/* vim: set foldmethod=marker: */

proc sort; by DESCENDING numb lname; run;

 /* View browse SASHELP library */
options ls=180;proc contents data=SASHELP._all_ /*NODS*/;run;

 /* What SAS products are licensed / installed? */
proc setinit noalias; run; 
 /* Apply setinit (to an expired license SAS - TODO does it work for a normal system?).  May be simpler just to right-click a setinit.sss file */
C:\Program Files\SAS Institute\SAS\V8>sas.exe -setinit -sysin c:\ -config "c:\Program Files\SAS Institute\SAS\V8\sasv8.cfg"

 /* Convert character constant date to character and SAS date to number (easiest date convert conversion) */
%put %sysfunc(putn('30OCT1965'D, 8.));
%put %sysfunc(putn(17325, DATE9.));

 /* Canonical read in readin infile input text CSV file: */
data Val500_Fielder_DIVI_Granulation; infile F DLM=',' DSD MISSOVER LRECL=2600 FIRSTOBS=3; input Product :$40. mydt :DATE. ... ; run;
 /* DSD "data sensitive delimiter" treats two consecutive delimiters as a missing value and removes quotation marks from values */

 /* Compress spaces from a numeric macrovariable: */
%let c = %sysfunc(compress(&c));

 /* Count spaces in a macrovariable by compressing them away */
%let l1=%length(&spacey); %let c=%sysfunc(compress(&spacey)); %let l2=%length(&c); %let csp=%eval(&l1-&l2);

 /* Remove commas and quote delimiters from mvar */
%let X=%sysfunc(compress(%quote(%sysfunc(translate(%quote(&S),' ',','))),'"'));

 /* Extract basename shortname stem from a fully qualified path: */
%let fq = %sysfunc(reverse(&fq)); %let basename = %sysfunc(reverse(%scan(&fq, 1, '\')));

 /* Remove last 4 characters of sting */
stem_with_end_removed=reverse(substr(reverse(s), 4));

 /* Delete specific characters, like regex s/foo// */
phone = compress(fullphone, '()- ');

 /* Substitute specific characters, like regex s/-/_/g */
sBatch1Code = translate(sBatch1Code, '_', '-');

 /* Substitute specific words, like regex s/foo/bar/g */
sBatch1Code = tranwrd(sBatch1Code, 'foo', 'bar');
sBatch1Code = tranwrd(sBatch1Code, 'foo', '');

 /* Canonical if then else macro: */
%if &i eq 2 %then %do; %let fqds=8ZP2432; %end; %else %do; %let fqds=32; %end;

 /* Rename vars to avoid "WARNING: Variable mfg_batch already exists on file WORK.VALTREX_PRODUCTIONANDANALYTICAL." */
proc sql; select * from (rename=(region=myyr subsidiary=mysub)) ; quit;

 /* View, display, print format permanent stored formats */
proc format library=WORK FMTLIB; run;

%let previousMonth = %sysfunc(intnx(MONTH, %sysfunc(today()), -1));

 /* Store as numeric */
time_point = input(time_pointSTR, F4.);

 /* Fast proc means */
proc means data=tmp; class time_point; var resultnum; run;

 /* Stupid SAS error message V8 at least: */
NOTE: BY-line has been truncated at least once.  /* fix with options ls=max */

 /* Left align a numeric into a character */
numlike=put(num, 6. -L); 

 /* View List and Log in my ;z map vim session */
:args %:r.log %:r.lst

 /* Canonical SELECT (case) statement */
select ( storeno ); when ( 81,83, 12 ) delete; when ( 73 ) put 'okthen'; otherwise; end;

 /* System call */
options NOxwait; data _NULL_; x "start lelimssumres01a&nm..sas7bdat"; /* 0 for success */ %put Windows status is &SYSRC; run;

 /* Remove all formats in dataset */
data foo; format _ALL_; run;

 /* Go back 1 year */
%let thisyr = %sysfunc(year("&SYSDATE"d)); %let minyr = %eval(&thisyr-1);

proc export data=VenHFA_analytical_individuals OUTFILE= "\\rtpsawnv0312\pucc\VENTOLIN_HFA\Output Compiled Data\CSV VenHFA_analytical_individuals.csv" DBMS=CSV replace; run;

filename HERE '.'; %let pwd=%sysfunc(pathname(HERE)); 

Patches installed:
C:\Program Files\SAS Institute\SAS\V8\core\sasinst\hotfix\

dataset_exists = %SYSFUNC(EXIST(mydataset));  /* 1 yes, 0 no */

ods PDF file='c:/temp/t.pdf';; ods PDF close;

 /* Eliminate garbage from a normally numeric field.  Keep Log clean. */
proc format; invalue NUMONLY(UPCASE) -999999999 - 999999999 = _SAME_ OTHER = . ; run; data clean_numbers_only; input mynum NUMONLY9.; ...

 /* Avoid this v8 problem by not using empty parentheses on macro calls */
180: LINE and COLUMN cannot be determined.

 /* Hardcoded literals in SQL select query */
select distinct 'literal ' as hardcodedfieldname, region 'display reggy all for rows' format=$5., product from

 /* Macro index search */
%if %index(&the_type, natmer) %then %put found a natmer;

 /* Canonical transpose, stat goes as column now */
proc transpose data=foo; by store; id _STAT_; var totdol; run;

libname INXML XML "&SYSPARM\&prodname\CODE\util\&DATASRC..xml" access=READONLY; proc contents data=INXML._all_;run; data tmp; set INXML.table; run;

 /* Default DM keys command line command focus SAS: <F11> PGM WPGM LOG OUT NUMS */

Change default WORK location (PC SAS): edit near EOF -WORK
C:\Program Files\SAS\SAS 9.1\nls\en\SASV9.CFG

Right click C:\Program Files\SAS Institute\SAS\V8\core\sashelp\setinit.sss to install license

 /* Display each line of textfile as it's read-in using INPUT statement */
put '!!!' _INFILE_;

 /* Submit the top n lines in SAS Editor - good for debugging like sasrun's endsas; trick */

 /* Show order by most frequent first */
proc freq data=students order=freq; tables name / nocum; run;

 /* Loop all characters in dataset: */
array cs _CHARACTER_; do over cs; if cs eq: 'foo' then cs = 'bar'; end;

 /* Single trailing at sign (for ID field) @ vs. Double trailing (for repeating blocks) @@ */
@  holds record in input buffer so that logic can be used to figure out which (next) INPUT statement to us.  More than one INPUT statement exists in data step.  Releases when control returns to top of data step.
@@ holds a record across multiple iterations of the DATA Step to allow reading multiple obs from a single line of raw data.  A single INPUT statement exists in data step.  Releases when the end of the raw RECORD is reached  or an @[@]-less INPUT statement is encountered.

 /* SAS Date format checker: */
data _null_; d1 = input('01-JAN-60', DATE9.); d2 = input('01/01/2009', MMDDYY10.); put _all_; run;

 /* Build large dataset: */
proc surveyselect out=stacked samprate=1 reps=5; run;

 /* 2 years ago */
%let thisyr = %sysfunc(year("&SYSDATE"d)); %let minyr = %eval(&thisyr-2);

 /* What SAS day number is one year ago from today? */
%let mindt = %sysevalf(%sysfunc(date())-365);
...  if test_date > &mindt; ...

 /* Save output as excel CSV file. v8 at least */
ods CSVALL file='junk.csv'; proc print; run; ods CSVALL close;

 /* char2num */
numdollars = input(chardollars, COMMA7.);  /* 123,456 */
 /* num2char */
devicealp = put(devicenum, 8. -L);

 /* Suppress SAS Log "NOTE: Invalid argument to function INPUT at line..." */
y=input(anum2, ? BEST. -L);

 /* SAS atoi ASCII (character) to integer (numeric) conversion statement (think "I"NPUT is closer to "C"har so use that to convert a char): */
yrtext='2003';  yrnum=input(yrtext, F4.);
yrtext='2003';  yrnum=input(yrtext, ?? F4.);  /* avoid Log errors if char data can't convert to num */
 /* SAS itoa integer (numeric) to ASCII (character) */
yrnum=2003; yrtext=put(yrnum, 8.);
data v3(drop=NUM:); set v012(rename=(instance=NUMinstance)); instance = put(NUMinstance, 8.); run;

 /* num2char2date */

options NOlabel;  /* prevent stupid proc sql default from displaying labels instead of varnames */

 /* View control and non numchar characters: */
... c=compress(comments1159,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');  ...

 /* Linehold using @ */
data _null_;
  file X21;
  put 'SELECT NAME, IP_TREND_TIME, IP_TREND_VALUE FROM "23034794.Vessel.Pres.PV" WHERE IP_TREND_TIME BETWEEN ' @; *** '02-APR-10 00:00:00' AND '21-APR-10 15:00:00';
  put "&IP21START and &IP21END";

 /* Convert to Oracle formatted datetime e.g. 21-MAY-98 02:30:37 is Oracle format 'DD-MON-YY HH24:MI:SS' */
proc format; picture ORADTT other='%0d-%b-%0y %0H:%0M:%0S' (datatype=datetime);run; data; s='21May98:02:30:37'DT; call symput('IP21START',"'"||trim(left(put(s, ORADTT.)))||"'");run;

 /* SAS IDE command key shortcuts */
F11 out->Result log-->Log lst-->Output wpg-->Enhanced Editor

 /* proc sql &SQLRC is 0 when there were no errors */

 /* 10 seconds */
data _null_; x=sleep(10); run;

if first.storeno and last.storeno then put 'firstdot lastdot says there is only one of these unique values: ' storeno;

 /* Assigned automatically by SAS */
SASUSER libname e.g.: C:\Documents and Settings\rsh86800\My Documents\My SAS Files\V8

 /* Display editor line numbers (Enhanced Editor etc) */

 /* SAS Program Editor (*not* Enhanced) where n is num of lines */
Cn/CC copy  Dn/DD del  In insert  Mn move  Rn repeat  A after  B before  undo (in cmdline)

 /* View input file text file in a SAS IDE window */
filename f 'bladerun_crawl'; proc fslist file=f;run;

 /* SAS Truth - True is 1 (or anything other than False), False is 0 or . */

 /* Distributive input statement */
input (name1-name12) ($)  @@;
input (Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) (1.);  /* read raw 111222333444 */

array elements{5} $2 _TEMPORARY_ ('H','He','Li','Be','B'); /* can't use '{*}' here */
 /* Multidimensional array 3 rows, 25 columns: 1-25 26-50 51-75 */
array a{3,25} v1-75;  /* to access v50: a{2,25} */

 /* Standard, SAS column input readable, numerics: -15, 15.4, +.05, 1.54E3, -1.54E-3  But still may be able to use formatted input, COMMA12.2 etc, for nonstandards ($ or % or ,). */

 /* Ampersand informat input modifier accepts embedded space so data must be delimited by TWO or more spaces */
input name &$12.  score1  score2;

 /* Fixed fields can be readin via column input (standard data only) or formatted input (either).  Freeform fields can be readin via list (or modified list "&" ":") input */

 /* Free-format input (space delimited etc) - use list input and only name each var and specify its type */
 /* Modified list can read spaces in vars and handle non-standards like commas in numbers */

 /* Canonical SAS DATETIME. format examples: */
30May2000:10:03:17.2  DATETIME20.
30May00 10:03:17.2    DATETIME18.
30May2000/10:03       DATETIME15.
 /* TIME portion must be delimited by a colon, minimum width is TIME5. */

 /* Canonical DATETIME convert to human */
data _null_; x=put(1614549716, DATETIME18.); put x=; run;

 /* Default input column pointer control starts at position 1.  After reading a piece of data it rests 1 column to the right of that data. */
 /* Column pointer controls: @n +n */
 /* Line pointer controls: / (relative, sequential)  #n (absolute, non-sequential) */

 /* _ERROR_ is a boolean */

 /* Avoid proc print "ERROR: Unable to allocate sufficient memory. At least 1168534K bytes were requested. You must either increase the amount of memory available, or approach the problem differently.  ERROR: Out of memory." */
data _null_; set _LAST_; file LOG; put (_ALL_)(=); put; run;

 /* Good printf for debugging */
data _NULL_; set _LAST_; file LOG; put '!!!DataLinkSQLPlusWSAdapterCon=================='; put (_ALL_)(=); put; run;

 /* Determine how many parameters were passed in */
%let l1=%length(&SYSPARM); %let c=%sysfunc(compress(&SYSPARM)); %let l2=%length(&c); %let csp=%eval(&l1-&l2+1);

 /* Take 2nd thru last parameters passed in as a single string (to be iterated later) */
%let sp=%str( ); %let pos=%index(%bquote(&SYSPARM), &sp); %let pxall=%substr(%bquote(&SYSPARM),&pos);

 /* Enquote for oracle statement syntax */
%let today=%str(%'%sysfunc( today(),mmddyy10. )%');

%let STARTDT=%sysfunc(putn(%sysfunc(datetime()), oradtt.));
%let today=%sysfunc(datetime());
%let prev=%sysevalf(&today-1*24*60*60);
%let ENDDT=%sysfunc(putn(&prev, oradtt.));

 /* Convert from human to SAS datetime */
data t; a=input("05-OCT-10 11:06:13", DATETIME18.); b=put(1601377424, DATETIME18.); run;

 /* If string contains substring 'zm' - weakly regex */
if name eq "&DESIGNATOR" and index(upcase(Value),'ZM');

 /* Load a dataset into memory only when dataset is used. */

 /* Canonical min max */
proc sql; select min(sampcreatets), max(sampcreatets) from tmp8.lims_0002e_avandamet; quit;
proc sql; SELECT min(resentts) format=DATETIME19., max(resentts) format=DATETIME19. FROM l.sumvaltrex01a ; quit;
proc sql; SELECT min(ts) AS mints format=ip21dtt., max(ts) AS maxts format=ip21dtt., "&STARTDT" as startdt, "&ENDDT" as enddt, count(ts) as cnt FROM &OUTPUTFILE ; quit;

 /* Simple timestamp datetime change */
data tmp1.ip21_0001e; set tmp1.ip21_0001e; maxts='12NOV10:19:45:10'dt; baselastrun='14NOV10:21:15:20'dt; run;

 /* Which files is SAS accessing?                                     ___________ _________________ */
c:/PROGRA~1/SASINS~1/SAS/V8/sas.exe -sysin -log t.log -nosplash -rtrace all -rtraceloc t2.log

 /* Print resolved macro code */
 /*                     keyword                            */
options MFILE; filename MPRINT '';

 /* GENMAX is the max number of datasets to rotate but each of those 7 gets an increment e.g. ip21_0002e_line8fillerBKUP#009.sas7bdat */
echo "libname l '//Rtpsawn323/DataPost/GSK/Zebulon/MDI';libname l2 'u:/tmp';data l2.ip21_0002e_line8fillerBKUP(genmax=3);set l.ip21_0002e_line8filler;run;" >| $UTMPDIR/ && $SASEXE -sysin "$UTMPDIR/" -log "$UTMPDIR/t7a.log";

 /* Variable range lists: */
 /* More subtle variable range lists: */
varA -character- varZ
varP -numeric- varT
 /* Canonical contents */
proc datasets library=SASHELP; contents data=shoes VARNUM; run; quit;

 /* Print to SAS Log without %put */
data _null_; file print; put #3 @10 "Data set &dsn. does not exist"; run;

 /* V8 undocumented informat: */
x='2005/6/30 12:30'; ymd_no_ampm=input(x, ymddttm16.);
ymd_ampm=input(z, ?? ymddttm18.);

 /* Distributed format put statement: */
put (mydt1 mydt2)(= DATETIME18. /);

 /* What do we have for ODS HTML etc: */
proc template; list tagsets; run;

SAS/SHARE remote server (running proc server) -> local client
SAS/CONNECT remote server (running spawner.exe) -> remote server (only the .sas file with rsubmit; endrsubmit; gets sent to server)

Error "Format F_APRCLS not found or couldn't be loaded for variable APRCLASS" opening dataset for viewing can be eliminated by submitting:  options nofmterr;

 /* Blank out empty wipe initialize datasets */
data ds_SAMPLE_1; run; data ds_SAMPLE_2; run;

 /* Canonical numeric array definition: */
array temperaturehour_arr {24} temp1-temp24;

xxSASxx END:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:

xxOTHERxx START:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-: {{{1

:: DOS directory list ls by age, order by oldest last.
dir /p /o:d

:: Short DOS names e.g. PROGRA~1
dir /x

' Visual Basic CRLF in decimal.  Octal is 015 and 012.  Hex is 0xD and 0xA.
Chr$(13) & Chr$(10)

Speed of a T1 line is 1.5MB/second  Speed of a T3 line is 45MB/second

10Base2  is 10 megabits/sec for 200 meters max cable length   10BaseT  is 10 megabits/sec over twisted pair

:: Find your MAC address on W2K (via the network, not the card itself).
> netstat -r
:: Find your W2K MAC address (I think it's directly from the card itself).
> nbtstat -A
:: or
> ipconfig /all

:: Connect map drive to a Windows share (cmd not rxvt). MUST BE UNMAPPED TO START.
net use x: \\rtpsawn321\e$ /persistent:yes /user:us1_auth\rsh86800n axhidhamx
:: Cygwin
net use x: '\\rtpsawn321\e$' '/persistent:yes' '/user:us1_auth\rsh86800n' conascent8
:: Disconnect unmap Windows shares (from a DOS prompt):
net use z: /delete
net use * /delete

:: Browse current connections (need single quotes only on Cygwin)
net view '\\emiake'

PrtScn copies the whole desktop, Alt-PrtScn copies just the app with focus.

Register a DLL on WinXP
c:\WINDOWS\system32\regsvr32.exe c:\WINDOWS\system32\MSRDO20.DLL

Microsoft's /dev/null
> attrib missingfile >nul

The colon ':' in a make Makefile can be read as 'depends on'

HTML email link:
<A HREF=" Mutt Users Digest&Body=subscribe">mailme</A>
<A HREF="">mailme</A>
<a href="mailto:&#98heckel&#64&#97&#116&#116&#46&#110&#101&#116">anti-spam email address</a>
<a href="mailto:&#98heckel&#64&#99&#112&#97&#110&#46&#111&#114&#103"></a>

<!-- Add an HTML button to go back in history: -->
<INPUT TYPE="button" VALUE="Back" onClick = "javascript:history.back()">
<!-- Go back 2 pages: -->
<INPUT TYPE="button" VALUE="Back" onClick = "javascript:history.go(-2)">

<input type="button" onclick="document.body.bgColor='lavender';" value="Change background color" />

Refresh newsgroups in slrn
/usr/bin/slrn --create -h -f /home/bheckel/slrn/ jnewsrc

' Plural vs. singular display.
sPlural = IIf((iFileCnt > 1), "s" & Chr(32), Chr(32))

User settings are saved in the Registry here:
HKEY_CURRENT_USER\Software\VB and VBA Program Settings\

:: DOS BAT -- original errorlevel is always 0.
:: Can view via cmdline:  echo %errorlevel%
if c:/foobar exists goto foo_ok
:: errorlevel will no longer be 0 if c:/foobar doesn't exist
:: This BAT test checks to see if the errorlevel return code is 1 OR HIGHER!
if errorlevel 0 goto y_is_available

' Determine which sheet you're using:
MsgBox "'" & ActiveSheet.Name & "' is the currently active worksheet."

Pico save and exit immediately: Ctrl-x

Add directory to DOS path:
set PATH=d:\newpath;%PATH%

Orthogonality -- the degree to which different features follow the same underlying principles in a programming language.

' Find last used cell in an Excel worksheet:

Run MySQL from command-line
$ mysql -t mydatabase < mysql.sql
Run PostgreSQL from command-line
$ psql invest < tmp.sql

' Iterate all Excel cells in a column range:
For Each c In [b1:b400]

Prevent other sites displaying your pages inside their frames:
<META HTTP-EQUIV="Window-target" CONTENT="_top">

Test an httpd Apache installation on localhost:

RGB hex  FF=100%  CC=80%  99=60%  66=40%  33=20%  00=0%
E.g. #00FF00 is 0% red, 100% green, 0% blue
or RGB:
00 is no color (black #000000), FF is full color (white #FFFFFF)

Byte size increments: mega, giga, tera, peta, exa, zetta, yotta

' Excel -- recognize a letter in a cell.

:: Test for existence of a file in BAT (note no quotes on echo):
if exist foo.txt echo ok

' Determine the date of the 1st day of the month 12 months preceding the
' current month was:
CDate(DateSerial(Year(Now), Month(Now) - 12, 1))

Dial-up connectoids by command line:
rasdial     <---to determine active connection name
rasdial "my connectoid" /d   <---or /disconnect

Hosts file on W2K: /c/WINNT/System32/Drivers/etc/hosts
Well know ports file on W2K: /c/winnt/system32/drivers/etc/SERVICES

<!-- Document may not be indexed, or used to harvest more links. -->
<meta name="ROBOTS" content="NOINDEX" content="1200">

Well known ports search (e.g. FTP is 21) on Unix:
cat /etc/services | grep -e ^http -e ^ftp -e ^ssh|grep tcp

Capture current Cygpath in Cygwin:
cygpath -w $PWD
cygpath -w `pwd`

Start PostgreSQL on Cygwin:
$ ipc-daemon & postmaster -D ~/pg/data >| ~/pg/data/pg.log 2>&1 &
Stop PostgreSQL on Cygwin:
$ pg_ctl -D ~/pg/data stop 
kill -9 [ipc-daemon's pid]

Show Windows pids (winpid) on Cygwin:
ps -W

' Does a directory folder exist?
If Dir(c.Value) = "" Then MsgBox c & " not exist"  End If <---FAILS!!!
' OK
If Len(Dir(c.Value, vbDirectory)) = 0 Then MsgBox c.Value & " not exist" Exit Sub

Determine a Windows user's hostname from an IP:
c:> nslookup

Pop up new window using only HTML
<A HREF="" TARGET=_BLANK>Spawn new window

Set up ssh ssl tunnel:
ssh -f -L 110:localhost:110 -l bheckel

Mozilla cookies:
/c/Documents\ and\ Settings/bqh0/Application\ Data/Mozilla/Profiles/default/

On CDC mainframe a cylinder is just less than 1MB:
Track==56,664 bytes  Cylinder==15 tracks (ie Cylinder==849,960 bytes)

# HFS JCL job submission:
submit 'bqh0.pgm.lib(include)' && for i in 1 2; do sysout -v|tail -1; sleep 7; done

format c: /S     <---also write autoexec.bat, etc.

Find info in horribly nested directory:
find "K:\ORKAND\System Documentation" | less
#                                    TODO xargs?
find "K:\ORKAND\System Documentation" | grep -i truct

Access parameter query:
like [Enter Partial Name] & "*" 
like "*" &  [Enter Partial Name] & "*" 

VB Date is 8 byte floating point value.  Integer portion is days since Dec 30,
1899. Fractional portion is pct of day completed.
E.g. 5/22/97 at 3:00pm is 35572.625

Copy cp entire dir from MVS (Z/OS) to HFS (hfsdir must already exist):
cp "//'dwj2.vscp.pgmlib'" dwjlib/
Copy single file from MVS (Z/OS) to HFS mainframe.  Mainframe copy cp.
cp "//'BQH0.INC.SASLOG'" ~/tmp/testing/ && vi ~/tmp/testing/
Copy cp single file from HFS to MVS (Z/OS)
cp "//'bqh0.pgm.trash(tryacc)'"
FTP navigation on MVS:
cd "//'dwj2.util.library'"
FTP deletion on MVS (note fscked up quotes, must be "'... ):
del "'DWJ2.FLNAT04.USRES'"

Unpack a normal unix tarball on EBCDIC HFS without tar:
pax -rvkf vim-6.0-rt2.tar -o from=ISO8859-1,to=IBM-1047

Copy and submit a mainframe job via Vim on USS.  Mainframe copy cp.  
Chain two commands in Vim.
:!cp % "//'bqh0.pgm.lib(%:t:r)'" \| :!sub 'bqh0.pgm.lib(tsaaaaq)'

Python help
>>> print open.__doc__
>>> help("open")

View an MVS mainframe file on HFS side:
cat "//'bqh0.pgm.lib(tsaaaaa)'" | vi -

Refresh fast quickly -- Windows registry.
LOCAL/System/CurrentControlSet/Control/Update/UpdateMode 00 not 01

-- Across database access syntax SQL Server SQLServer
select count(*) from [W23PSQL01\Production].bpms_va.dbo.claims_pharmacy

-- Outer joins preserve the rows that don't match and pad the remaining columns with NULLs.  OUTER keyword is optional.
-- These words replace the comma between tablenames in old style Oracle (+) joins:

-- inner joins eliminate the rows that *don't* match

-- Built-in Scalar Function SQL Server SQLServer

-- Only on one table (Oracle v8 can't use JOIN ON syntax!)
select a.numb, b.numb from tmp1 a LEFT JOIN tmp2 b on a.numb=b.numb where b.numb IS NULL

SELECT DATEDIFF (YEAR, '1/1/2002', '1/1/2005')

Fast exit icon c:\windows\rundll32.exe user.exe,ExitWindows

-- Yesterday (24 hours ago) SQL Server SQLServer

-- SQL Server - similar to DESCRIBE in other databases SQLServer
USE sandbox
EXEC sp_help lu_prescriber
-- or less helpfully
EXEC sp_columns lu_prescriber

-- whoami
select user_name()

SQL Server < 2005 alternative to Microsoft SQL Server Management Studio
osql -L   # list available SQL Servers on network
osql -E -S 'W23PSQL02\PRODUCTION' -i t.sql -o t.out
osql -n -E -w 200 -d bpms_nd -S 'W23PSQL02\PRODUCTION' -i ckbpmsoutliers.step07.sql 
Interactive (GO to run and QUIT to exit)
osql -n -E -S 'w23psql02\PRODUCTION' -d bpms_mt
Interactive but feeding it from the commandline:
osql -n -E -w 200 -d bpms_ak -S 'W23PSQL02\PRODUCTION' -Q "select count(*) from bpmsoutliers"

-- sqlserver 2005 command line, counterpart to oracle's sqlplus
$ sqlcmd -S zebsamoc007 -d usprd1208 -i input.sql -o output.txt

-- ADO/SQLServer connection strings
Provider=OraOLEDB.Oracle.1;Persist Security Info=True;User ID=ods_zeb;Password=ZEBODS_ZB842;Data Source=ukprd613;
Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=usprd1208;Data Source=zebsamoc007

SQL Server 2005 (like Oracle's sqlplus, replaces osql & isql).  Must use cmd, not cygwin
U:\>sqlcmd -S zebsamoc007 -d usprd1208
1> select top 5 * from fwn.variablestp    2> go   ...n rows affected...   1> quit

U:\>sqlcmd /?
U:\>sqlcmd -S rtpsamoc008 -d ustst1236 -i t.qry -o t.res

-- now() for SQL Server SQLServer
select getdate()  or  select current_timestamp

-- Size of table in SQL Server database SQLServer
EXEC SP_SPACEUSED N'rheckel.[bpmsoutliersnc60]'

-- Copy an SQL Server table into a new one that does not already exist:
SELECT * INTO xBpmsOutliersNC60 FROM BpmsOutliersNC60 

-- Copy first few rows of Oracle table into new one that does not already exist:
INSERT INTO bobhlm SELECT * FROM links_material WHERE rownum<11;

-- Delete Oracle table (even if records exist in it):
DROP TABLE bobhlm;

--Get Oracle database instance version rack etc information v9+
select * from v$instance;

Works under Cygwin rxvt too
at 20:42 /interactive notepad

' Do not prompt user before overwriting:
Application.DisplayAlerts = False

-- Oracle prevent nulls from propagating:
SELECT ename, comm, sal, 12*sal+NVL(comm,0) ...

-- Oracle case insensitive
where ename LIKE UPPER('foo%')

-- Oracle exact date change
update mdpi_shift_downtime set mfg_shift_dt=TO_DATE('9/4/2007','MM/DD/YYYY') where Comment_Txt='Assembly Downtime Test'

-- Canonical Oracle SQL*Plus date examples (Oracle date less than etc)
WHERE e.hire_date < TO_DATE('12/31/1999', 'mm/dd/yyyy')
WHERE birth_date < TO_DATE('19400101', 'YYYYMMDD')
WHERE EntryTs >= TO_DATE('07-NOV-06 00:00:00','DD-MON-YY HH24:MI:SS')

-- Oracle date range
WHERE prod_sel_dt BETWEEN TO_DATE('01-JAN-10','DD-MON-YY') and TO_DATE('31-JAN-10','DD-MON-YY')

-- Oracle last few days search (if activity_dt is DATE formatted)
select count(*) from activity_log where activity_dt > (SYSDATE-3);

-- Oracle date only this month

select * from retain.fnsh_prod where prod_sel='Y' and trunc(prod_sel_dt)=trunc(sysdate);

-- Oracle generate random positive integer:
select ABS(round(dbms_random.normal*100,-1))  from dual;

-- Oracle update query samples: 
update pks_extraction_control set pks_level='' where pks_level='.';
update retain.fnsh_prod set prod_sel = 'N', prod_sel_dt = NULL;

-- Oracle SQL*Plus (like SELECT TOP 10 *... in SQL Server)
select * from activity_log where rownum<10;

-- Oracle last month
select ADD_MONTHS(sysdate,-1) from dual;

dbms_output.put_line('rpt at: ' || TO_CHAR(sysdate, 'dd-mon-yy hh:mipm'));

-- Oracle Business hours only
...if (TO_CHAR(sysdate, 'DY') in ('SAT', 'SUN') or
(TO_CHAR(sysdate, 'HH24') not between '08' and '18') ...

-- Oracle CASE or IF-THEN-ELSE shortcut, replacement
--                                IF  THEN     IF       THEN  ELSE
select prod_nm, decode(prod_grp,'MDPI','m','Solid Dose','sd','unk') from samp;

-- Format Oracle format if column too wide that truncation occurs in sql*plus window:
sql> col[umn] MFG_SPEC_TXT_A format a15
sql> column MFG_SPEC_NUM format 999      -- number width w/o zeros

-- Oracle update
UPDATE user_role SET user_role=5 WHERE user_nm LIKE '%Heckel%'
-- Oracle substring replace
UPDATE pec SET pks_txt=REPLACE(pks_txt,'GEN','new') WHERE pks_txt like '%GEN%';

-- Oracle date
select to_char(sysdate, 'Dy DD-Mon-YYYY HH:MI:SS AM') as "Current Time" from dual;  -- Wed 19-Aug-2009 02:51:33 PM  TODO is the 'AM' correct??
select to_char(sysdate, 'Dy DD-Mon-YYYY HH24:MI:SS') as "Current Time" from dual;  -- Wed 19-Aug-2009 14:53:41
select TO_DATE('16-JAN-06');  -- uses Oracle's default date format
select TO_DATE('15-may-2006 16:00:01','dd-mon-yyyy hh24:mi:ss') from dual; -- 15-May-06 04:00:01 PM
select * from activity_log where trunc(activity_dt)=TO_DATE('16-JAN-06','DD-MON-YY');
select TO_DATE('15-may-2006 16:00:01','dd-mon-yyyy hh24:mi:ss') from dual; -- 15-May-06 04:00:01 PM

-- Oracle date between
AND SS.EntryTs >= TO_DATE('01-JAN-05','DD-MON-YY') AND SS.EntryTs <= TO_DATE('31-DEC-05','DD-MON-YY')

-- Oracle spool (Windows).  Save Oracle SQL*Plus output to file foo.LST
sql> spool %TEMP%/foo qry
sql> spool off

-- Oracle check for duplicates, returns none if all samp_id are unique
select count(*) from samp group by samp_id having count(*)>1;

-- SQL*Plus
sql> show all
sql> set linesize 1000;
sql> set pagesize 9999;

-- Oracle high level view all database tables in current schema (may need sqlplus set pause ON)
SQL> SELECT table_name FROM user_tables;
-- Oracle high level view all database tables all available schema
SQL> SELECT table_name FROM all_tables;
-- Oracle list all schemas:
SQL> SELECT username FROM all_users ORDER BY username;
-- Oracle select top 10 rows of a table in order:
-- Oracle describe table
SQL> desc mytable

' ASP debugging:
response.write "mfg" & Request("Mfg_Shift") & <br><br>""
response.write "foo" & lstrEntryType
' or outside of code (hidden from user if white):
<font color=white><%= Request.Form("menutype") %></font>
<font color=red> <%= "debug " & Request("menutype") %> </font><br>
<font color=red> <%= "debug " & Session("AdminRole") %> </font>

' Since VB doesn't have substr(), can use this
MyCheck = "aBBBa" Like "a*a"

<form method="POST" name="foo" action="t.asp?MenuType=Batch Data">

-- Oracle how many rows of data in table (with a safeguard):
select max(rownum) from pks_extraction_control where rownum<1000000;

-- WARNING: LEFT INNER JOIN is a syntax error

-- Oracle's MINUS is EXCEPT in ANSI SQL

INSERT INTO links_material (matl_desc) VALUES ('Waiting for update from SAP')
INSERT INTO links_material (matl_desc, matl_mfg_dt, matl_exp_dt, matl_nbr, batch_nbr, matl_typ) VALUES ('Waiting for update from SAP', '01-JAN-1960', '01-JAN-1960', '0737003', '6ZP8404', 'MANL')

-- Oracle prompt (1st time only) for saved environment substitution variable:
select * from tst_rslt_summary where samp_id=&&sampy;

:: abort the gsk auto shutdown crap on WinXP
shutdown.exe -a
:: or 
/cygdrive/c/WINDOWS/system32/shutdown -a

-- Canonical sqlplus
SQL> define_editor=gvim
SQL> ed foo  -- sqlplus adds an .sql extension so probably don't need the -c vim stuff
SQL> @foo

-- Canonical sqlplus save spool output to file
set termout off; set linesize 2000; set pagesize 9999; spool u:/serevent.out; ...SQL...; spool off; quit;

spool u:/ahfa60stab.out;

-- userid/password@hostname
$ sqlplus pks/dev123dba@usdev388
$ sqlplus pks/dev123dba@usdev388 @c:/cygwin//home/bheckel/code/misccode/_sqlplusrc.sql
$ sqlplus pks/dev123dba@usdev388 @t.sql --need an exit; in t.sql to run standalone

SQL> define_editor='c:/program files/vim/vim70/gvim -c "set filetype=sql"'
SQL> set linesize 1000;  -- avoid truncation of results

-- PL/SQL print
set serveroutput on BEGIN DBMS_OUTPUT.ENABLE; DBMS_OUTPUT.PUT_LINE('Hello Word'); END;

-- Oracle (at least) make a copy of a database table

-- Oracle nonaggregated expression (rownum) in an aggregated query - SQL hack:
select rownum, a.* from (select cust, count(ord) from tbl group by cust) a;

-- Oracle view constraints if your drop table doesn't work:
select * from user_constraints where table_name = 'COUNTRIES';

86400 seconds in a day

// Javascript arrays
coffees = ["French Roast", "Columbian", "Kona"]
myArray = new Array("Hello", myVar, 3.14159)

# Where Ruby libraries are installed
ruby -e "puts $:"

Windows runs on little-endian platforms

Use gvim to edit source in Firefox:
search 'edit', toggle the boolean, add the path to the other one 
C:\Program Files\Vim\vim70\gvim.exe

On Error Resume Next  ' VB/ASP execute next line of code following the error

Dim multiple, vars, are, ok, singleline

ASP multiple statments on one line
<% x=3 : y=25 : z=x-y : y=x*z : z=x*x-z+y : y=5*3*z*2/x %>

ASP shorthand alternative to Response.Write(Date())
<%= Date() %>

SELECT * FROM funds ORDER BY transdt DESC  -- ASC is default

Foreign Key is that same value stored within MULTIPLE rows of the "detail" table

c:> echo %random%

Oracle YYYYMMDDHH24MISS date sample:

Hidden startup executables (not found in Programs:StartUp see also Powershell approach):
or under Cygwin:
$ regtool -v list '\machine\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'

select top 10 * from tbl  ' SQL Server & Access
select * from tbl where rownum<11  ' Oracle

:: doskey in DOS == alias in Unix
doskey vi=vim $1

// Source JavaScript
<script type="text/JavaScript" src="sortable.js"></script>

// CSS JavaScript misc
<link rel="stylesheet" type="text/css" href="crc.css"/> 
<style="cursor:pointer; color:blue; font-family:monospace; font-style:italic; border:2px solid black; background-color:red"; border-style:solid; padding:0px 1px 0px 1px;position:absolute>

// CSS inline style
<tr style="visibility:collapse;">
<table style="border: 1px solid black;">

<input type="button" value="On" onclick="myfn('msg',1); return false;">

Google Chart API,y&chxl=0:|Mar|Apr|May|June|July|1:||50+Kb
<img src=";chd=s:helloWorld&amp;cht=lc&amp;chxt=x,y&amp;chxl=0:|Mar|Apr|May|June|July|1:||50+Kb"alt="Sample chart" />

Browser HTML File URL

$ ~/bin/msgbox "my title" "my body" error

' Autorun VBA macro - create empty workbook, add code via Alt-F11, click
' Window : Hide, save as bob.xls in 
' C:\Program Files\Microsoft Office\Office10\XLStart\

' Autorun an Excel VBA macro:
Private Sub Workbook_Open() ...

:: Windows Desktop path:
C:\Documents and Settings\rsh86800\Desktop

# uptime for Windows 
$ systeminfo|grep 'Up T'

:: Remote restart reboot a Windows workstation:
c:\> shutdown -r -m \\zebwd08D26987
# Remote restart Cygwin version:
$ shutdown -r -m '\\zebwd08D26987'
$ /cygdrive/c/WINDOWS/system32/shutdown -r -m '\\zebwd08D26987'

:: Remote shutdown a Windows workstation:
c:\> shutdown -s -m \\zebwd04480k6c

Don't load Mozilla Firefox3 extensions addons:
c:\> firefox.exe -safe-mode

If lastgrp <> r.Value Then ... End If

' Write to a file instead of Immediate Window
fnum = FreeFile   Open "c:\temp\junk" For Output As #fnum   print #fnum "foo" & bar  close #fnum

' Wildcard like SQL
If lastgrp <> "none" And Not r.Value Like "T0*" Then ...

Word Doc equivalent to Ctrl-o in vim: Shift-F5

Points are a typesetter's standard unit of measure. There are 72 points to an inch. So a capital letter in 12 point font is one-sixth of an inch tall.  You can fit 6 of these 12 point letters stacked on top each other in an inch (12x6=72).

' Delete all selected items in a multiselect listbox
Private Sub cmdDeleteListItems_Click() Dim i As Integer For i = List1.ListCount - 1 To 0 Step -1 If List1.Selected(i) Then List1.RemoveItem i Next i End Sub

Vimperator Firefox:
C:\Progra~1\Mozill~1\firefox.exe -vimperator "+u 'c:\cygwin\home\bheckel\.vimperatorrc'"
C:\Progra~1\Mozill~1\firefox.exe -vimperator "+c ':h index'"
:dia console <--open error console :emenu <TAB> :h index :mes[sages] :se[t] :se[t] all :pref[erences] :pref! <--open about:config :res[tart] :addo[ns]  (<TAB> for all choices then <TAB> & <Shift><Tab> to navigate) :dia history

Windows shortcut Properties target box:
"C:\Program Files\Mozilla Firefox\firefox.exe" -vimperator "+u 'u:\code\misccode\_vimperatorrc'

Windows shortcut Properties target box:
"C:\Program Files\Vim\vim72\gvim.exe" -u u:\.vimrc

XML header: <?xml version="1.0" ?>
Same: <?xml version="1.0" encoding="UTF-8"?>

-- Oracle version:
SELECT * FROM v$version

-- Also allows determination of which oracle version(s) are installed
/oracle/app/oracle/product/9208HP64DB1_PAR/bin/tnslsnr LISTENER
/oracle/app/oracle/product/8.0.6/bin/tnslsnr LISTENER -inherit


-- Oracle are you listening listener?
$ ps -ef |grep lsn  # /oracle/app/oracle/product/8.0.6/bin/tnslsnr LISTENER -inherit
$ tnsping usdev100

-- Oracle are you pingable?
$ while true; do tnsping usprd259|grep OK|awk '{print $2}'|sed 's/^.//'; sleep 120; done;

$ telnet locahost http
# or
$ telnet locahost 80
GET / HTTP/1.0

:: Count network hops
c:\> tracert

Windows Task Manager alternative key combination: Ctrl+Shift+Esc 

Open Windows Event Viewer from command line:  eventvwr

<!-- Redirect moved forward new address, 0 indicates immediately -->
<meta http-equiv="refresh" content="10; url=">

Windows Task Manager: Ctrl+Shift+Esc 

:: Purge get new network IP address WinXP
ipconfig /flushdns; ipconfig /release; ipconfig /renew

:: computername, userid, domain, OS version ...
net config workstation

' VB date constant
Dim date1 As Date = #4/10/2008 6:30AM#

=WORKDAY(TODAY(),B17)  where B17 is number of business days into the future

' Excel count workdays date range only (e.g. custom format '03-Apr-09 16:00 06-Apr-09 10:30 spans wkend and returns 0.77
' or total business hours to resolve

' Subquery (Oracle at least)
select * from eforms_extract.zebulon_request_detail where request_id=(select max(request_id) from eforms_extract.zebulon_request_detail)

Oracle SQLPlus
SQL> ed  -- edits afiedt.buf (assuming a query has already been run)
SQL> r  -- run query

-- SQL Server date datetime literal or  { d '1990-10-02' }  { t '13:33:41' }
WHERE fwn.VariableStp.dtSplTakenTime= {ts '2008-11-21 15:46:59.727'}

-- SQL Server version:  SELECT @@VERSION

-- SQL Server like Oracle TO_DATE: 
WHERE  batch_time > {ts '2008-02-13 00:00:00.000'}

<!-- Clear textbox on entry click -->
<INPUT NAME="the_batch" TYPE="text" VALUE="Enter batch" onClick="javascript:value=''; return false">
<INPUT NAME="mytextbox" TYPE="text" VALUE="Click to begin editing" SIZE=70 onClick="this.value='';return false">

:: Last logon login times
dir "%userprofile%\ntuser.dat.LOG" /ah /s

-- Who is logged into Oracle:
select * from v$session;

start /b /min /wait notepad.exe
:: waits for Notepad to exit before starting a new one
start /b notepad.exe

XML namespaces:
<xyz xmlns:books="" 

<?xml-stylesheet type="text/xsl" href="hello.xsl"?>

<xsl:variable name="Str_OutputFilePath">
<!-- DEBUG XSLT -->
<!-- foo <xsl:value-of select="$Str_OutputFilePath"/> bar -->

:: Run checkdisk check disk on USB drive E: without rebooting:
chkdsk /f e:

:: Check for a parameter passed
if "%1"=="" goto noparms

To see logged on users in Windows 2003 - "Computer Management" "Shared Folders" view current open shares and sessions 

^ is DOS cmd line continuation... like a backslash at the end of the line in unix

-- Pass a parameter to sqlplus (see ~/misccode/oracle_process_id.sql or wantsampid*)
... AND    spid = '&1'; ...

-- Oracle sqlplus do not display query results (usually when sending output to .out file)
set termout off

:: Determine .NET version installed installation

<div style="font-family:arial; color:blue; text-decoration:underline; font-weight:bold; font-size:200%">Newer approach - HTML using CSS</div>

COALESCE(field1, field2) -- SQL takes the first non-null value it can find

' Vim fold folding
:se fdm=manual

<script type="text/javascript">document.getElementById('txtCDInfo').innerHTML="new text!";</script>

 /* CSS */
body { background-image:url('../images/DataPost.png'); background-color:grey; background-attachment:fixed; background-repeat:no-repeat; background-position:center; }

:: Delete a Windows XP Service:
c:/> sc delete <the svc name>

Factorial: 6! is 6*5*4*3*2*1

Fibonacci each number is the sum of the preceding two: 0 1 1 2 3 5 8 13 21 ...

OldNew percentage change: Take the new, "current value" and divide it by the
old, obsolete value. Subtract 1.00 (or 100%) from the result.

Disable screensaver lock Windows XP (see also code\misccode\ScreenSaverIsSecure_Make0.reg)
ScreenSaverIsSecure 0

Windows Explorer shortcut Target box tree view:
%windir%\explorer.exe /e,u:\_go

WinXP icons

:: Google DNS
nslookup hostname
nslookup hostname
:: Level 3 DNS
nslookup hostname
nslookup hostname
:: OpenDNS
nslookup hostname
nslookup hostname
tracert -d

DNS test

:: Windows - what runs at startup etc.

# Benchmark a network speed problem
$ time vi -c :q $u/junk

-- Increment counter in Oracle

runas /User:Administrative_AccountName"mmc %systemroot%\system32\inetsrv\iis.msc"

Check XML file for well formedness errors parse validate:

MIME type:

<!-- HTML5 -->
<!DOCTYPE html>
<html lang="en"> ... </html>

-- Oracle regex - returns 250/50 MCG
select regexp_substr(upper('Advair Diskus Inh Pwdr 250/50 mcg 60D'),'\d+/[^/]* *MCG') as strength2 from dual

Virtual Box after setting \code (put the mount cmd in /etc/rc.local for debian distros)
mkdir ~/code; sudo mount -t vboxsf -o uid=1000,gid=1000 code /home/bheckel/code

-- Oracle not equal !=

/* Linking to external CSS stylesheet: */
<head><link rel="stylesheet" type="text/css" href="stylesheet.css" /></head>

/* Embedding styles within a page: */
<style type="text/css"> ... styles ...  </style>

/* Example of defining style for an entire page: */
body { margin:0; padding:8px 4px 12px 4px; color:#ffbf11; background:#000000 url(images/space.gif); }

:: Win7 enable hibernation
> powercfg /hibernate on

Ctrl-r odbc commandline odbcad32

-- Build Oracle GRANT statements for @myfilesql (run as pks)
select  'grant select,insert,update,delete on ' || tname || ' to pks_user' from tab

-- Build Oracle SYNONYM statements for @myfilesql2 (build these as pks but run them as pks_user) $ sqlplus pks_user/pksu388@ustst581 @synonyms.sql
select 'create synonym PKS_USER.' || tname || ' for PKS.' || tname || ';' from tab

Remote Desktop C:\WINDOWS\system32\mstsc.exe /admin

<?xml-stylesheet type="text/xsl" href="file:///c:/datapost/cfg/DataPost_Configuration.xslt"?>

# git new branch:
git branch mynewbranch; git checkout mynewbranch
# or just branch and checkout in one swoop:
git checkout -b mynewbranch

# git switch branches
git checkout master

# git merge
git checkout master && git merge mynewbranch && git branch -d mynewbranch
# git commit mantra (svn-ish)
git add . && git commit -am 'another bitfiddle'

git help branch

COMMAND=st=cygstart "%f"

:: Delete all files in a directory using .bat
DEL z:\Data_Trending\MDPI\*.* /Q

-- SQL Server
WHERE datepart(year,insert_date)='2005' AND datepart(month,insert_date)='7' AND datepart(day,insert_date)='31'

Powershell help e.g.:
help csv
Get-Help * | Format-Table * -auto
###Get-Help * | Format-Table * -wrap | Out-File env:TEMP/tmp.txt; gvim env:TEMP\tmp.txt
Get-Help * | Format-Table * -wrap | Out-File tmp.txt; gvim tmp.txt

# Powershell's which(1) or type(1):
Get-Command ls  # or  gcm ls
$c = Get-Command ping; $c | Format-List *

# Powershell available formatting shapes:
gcm format-* | ft name
# Powershell available cmdlets:
gcm out-* | ft name

# Powershell provider abstraction "drive letters" (optional slash)
ls variable:/  # internal variables, system and user-defined (e.g. $null $true ...):
ls c:/
ls HKLM:/  # registry "drive" 
ls function:
(dir function:/).count
rm function:/myfunc
ls env:  # Powershell's SET:
ls env:\PAT*
ls env:\path | Format-Table * -wrap  # show wrapped columns:

# Powershell Search loaded assemblies:
[AppDomain]::CurrentDomain.GetAssemblies()|ft -wrap  # show the '...' part at far right
[AppDomain]::CurrentDomain.GetAssemblies()| %{ $_.GetExportedTypes() }|where {$_ -match 'Paper*'}

new-psdrive -name mydocs -psprovider filesystem -root (resolve-path c:/*documents)  # create drive mydocs:

# Powershell create a test file:
'"Hello world!"' | Out-File test.ps1

# Powershell allow scripts to run:
get-executionpolicy  # what is current setting
Set-ExecutionPolicy RemoteSigned
Set-ExecutionPolicy Unrestricted

# Powershell alias:
Set-Alias vi "C:\Program Files\Vim\vim72\vim.exe"
Set-Alias runmyscript .\myscript.ps1
Set-Alias runmyscriptfromanydir $env:appdata\myscript.ps1

# Powershell grep search files:
select-string -quiet -CaseSensitive "Wildcard Description" $PSHOME/about*.txt
dir -rec -filter *.log $env:windir\system32 | select-string -list fail | ft path  # only display path of 'fail' matches in recursive directory search

# Powershell grep search select output of a command:
$s = ipconfig; $s | Select-String 'addres'

# Powershell count of files in directory (force to return array in case there are 1 or 0 files in the dir):

# Powershell grep search select 'Error' string output of log files, counting what it found (see switch.ps1, Powershell's SELECT or CASE, for a non-cmdlet alternative):
dir *.log | select-string -list Error | format-table path, linenumber -auto

# Powershell array (then just type $myarr to echo it to console or $myarr[0] or $myarr[-2] etc.)
$myarr = "hello", 'World', 1, 2, (Get-Date);  $myarr | ForEach-Object { "Current element: $_" }
$myarr = "hello", 'World', 1, 2, (Get-Date);  Foreach ($element in $myarr) {"Current element: $element"}  # faster if results are in a var and acquisition time is short

# Powershell FOR EACH loops (the foreach alias works context sensitively):
Get-Process | ForEach-Object { $ }  # cmdlet approach, implicitly uses $_, no slurp, 1 line at a time
$l=0; foreach ($f in dir *.txt) { $l += $f.length }  # flow control statement approach, have to use $l, slurps whole file

# Powershell ForEach-Object extreme shorthand:
1..5 | % { $_ + 2 }
1..5|%{$_%2}  # obfuscated modulus :)
1..5|%{ping localhost; sleep 600}  # same as  while true; do ping localhost; sleep 600; done;

# Powershell hash.  @{} is an empty hash.  $hash['IP'] or $hash.ip to access this one:
$hash = @{Name = "PC01"; IP=""; User="Tobias Weltner"}

# Powershell pipeline:
dir | Sort-Object length | Select-Object name, length | ConvertTo-Html | Out-File junk.htm
./junk.htm  # view it in browser

# Canonical sort and find largest file
$a = dir | sort -property length -descending | select-object -first 1

# Powershell query an object:
Get-Service | Where-Object { $_.Status -eq "Running" }
Get-Process | Where-Object { $ -like 'micro*' } | Format-Table name, description, company
Get-WmiObject Win32_Service | ? {($_.Started -eq $false) -and ($_.StartMode -eq "Auto")} | Format-Table
Get-WmiObject Win32_Service | ? {($_.Started -eq $false) -and ($_.StartMode -eq "Auto")} | Format-Table name, startmode, pathname

# Powershell rc .rc profile file C:\Documents and Settings\rsh86800\My Documents\WindowsPowerShell\
gvim $((Split-Path $profile -Parent) + "\profile.ps1")

# Powershell's Option Explicit
Set-PSDebug -strict

# Powershell concatenation:
"today date: " + (get-date)

# Powershell formatting operator -f:
"today date: {0:D} " -f (get-date)
"{1:C} {0}" -f "foo", 123  # $123.00 foo

# Powershell find top Windows processes consuming a high greatest most amount of memory
ps | where { $_.WorkingSet -gt 20000000 }  # from commandline
Get-Process | Where-Object {$_.WorkingSet -gt 20000000}  # from script

# Powershell find then sort Windows processes consuming the high greatest most amount of memory
ps | sort -desc ws | select -first 1  # firefox :-(

$('bbb','ccc','aaa' | sort )[0]  # aaa

# Powershell strings
('hello').Split('l')  # or just "hello world".split()

# Powershell regex -match -cmatch -imatch -notmatch -replace ...
$ip = ""  # String object
$ip -match "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"  # -cmatch for case-sensitive search

# Powershell regex substitute
"Mr. Miller and Mrs. Meyer`n" -replace "(Mr.|Mrs.)"  # delete
"Mr. Miller and Mrs. Meyer`n" -replace "(Mr.|Mrs.)", "Our client"  # replace

$file = $file -replace '.txt$','.ps1'  # like regex s/\.txt$/\.ps1/  TODO why is '.' not a regex char here?

# Powershell regex capture
'abcd' -match '(a)(b)(c)'  # $matches[0] holds 'abc', matches[1] holds 'a' ...

# Powershell regex named capture
#                 _____   _____  _____   _____
"abcdef" -match "(?<o1>a)(?<o2>((?<e3>b)(?<e4>c))de)f"  # $matches['e3'] holds 'b' ...

# Powershell time a process run
(Measure-Command {Dir $home -include *.ps1 -recurse}).TotalSeconds  # slower b/c supports regex
(Measure-Command {Dir $home -filter *.ps1 -recurse}).TotalSeconds

# Powershell search for largest files
Dir $home -recurse | Where-Object { $_.length -gt 100MB }

# Powershell count of files found
@(Dir $home -recurse -include *.bmp,*.png,*.jpg, *.gif).Count

# Powershell head (use -last for tail) read file:
Get-Content $env:windir\windowsupdate.log | Select-Object -first 10  # no need to do any formal open-write-close in Powershell

# Powershell registry list start-up key contents
Get-ItemProperty HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Run

([xml](new-object net.webclient).DownloadString("")) | format-table title,link

# Powershell is file1 newer than file2?
(dir file1.txt).lastwritetime -gt (dir file2.txt).lastwritetime

# cmd and Powershell history - F7

# Powershell find(1) -name -recurse
dir -rec -fil *.dll | where {$ -match "system.*dll"}

# Powershell subexpression in a string to present data:
"Numbers 1 thru 10: $(for ($i=1; $i -le 10; $i++) { $i })."

# Powershell hash, create then access (any assignment is by REFERENCE):
$user = @{}; $user = @{ FirstName = "John"; LastName = "Smith"; Phone = "555-1212" }; $user; $user = @{ FirstName = "John"; LastName = "Smith"; Phone = "555-1212" }; $user.Keys

# Powershell array, create then access (any assignment is by REFERENCE):
$a = @(); $a = 1, 2,3, 'cat', 4; $a; $a[3]; "$a"

# Powershell slurp read file in PWD (in this example if on C:) write new file, substitute and replace specific phrases in a text file:
${c:bladerun_crawl} -replace 'in (an|the)','xxx $1' > new.txt  # note single quotes still allow interpolation of $1 !
# In-place edit (careful with very large files, it's done in-memory):
${c:bladerun_crawl.txt} = ${c:bladerun_crawl.txt} -replace 'in (an|the)','xxx $1'

# Powershell Fibonacci sequence (swap values current & previous without a temp variable):
$c=$p=1; while ($c -lt 100) { $c; $c,$p = ($c+$p),$c }

& "command with space in name.exe"

c:\> PowerShell.exe "& './my script.ps1'"  # if space in scriptname need the call operator: '&'

# PowerShell scriptblock like awk, perl etc.'s BEG - process - END
1..5 | % {$i=1;"beg: $i"} {$_ + 2 + $i++} {"end: $i"}

# PowerShell list interrogate all object methods for the class:
[string] | get-member -static  # string class
"foo"|get-member  # string class
12|gm  # Int32 class
$HOST|gm  # interrogation which tells you Version
$HOST.version|gm  # ...etc.

# Ask PowerShell - does a Reverse method exist for this class?:
[array] | gm -static reverse  # it does

# Powershell Convert string to array using a cast:
$a = [char[]] "foobar"
[array]::reverse($a)  # reverse the string
$a=[string]::join('',$a)  # make it a real String again verify- $a.gettype().fullname

# Powershell Error trap and view:
$err = dir nosuch 2>&1; $err | fl * -force  # or use default $error[0]

trap { "PowerShell trapped handled exception!" } 1/$null

(get-eventlog powershell)[-5..-1]

# Powershell Lookup figure out backward engineer the signature of a .NET method
('hello'|gm split).definition  # you see StringSplitOptions so then...
[StringSplitOptions] 'abc'  # force an error to tell you what are the valid enumerations

# Powershell Split string on numbers
[regex]::split('Hello-1-there-22-World!','-[0-9]+-')  # count matches:  [regex]::split('Hello-1-there-22-World!','-[0-9]+-').count

# Powershell Build and use a regex object:
$pat = [regex] "[0-9]+|\+|\-|\*|/| +"  # view all object methods (spoiler - we will choose Match()):  $pat|gm
$m = $pat.match("11+2 * 35 -4")  # the do $m|gm to find the Success() method

# Powershell Create dummy files for testing:
1..3 | %{ "This is file $_" > "junkfile$_.txt"}

param($name='world')  # must be 1st executable line in script
"Hello $name!"

# Powershell All programs and date of installation:
get-wmiobject -class "win32reg_addremoveprograms" -namespace "root\cimv2" | select-object -property Displayname,Installdate

function cd.. { cd .. }  # convenience like cmd.exe

# DEBUG debugging printing:
$host.ui.writeline("red","green", "Hi there")

# Powershell Command line prompt customization override
function prompt { $host.ui.rawui.WindowTitle = "PS $pwd"; "PS> " } # prompt function is a builtin, in DOS it's an env var:  echo %prompt%
function prompt { "$((get-date).DayOfWeek)> " }

# Compare PowerShell with ksh, kill all processes hogging 10MB memory or more:
$ ps -el | awk '{ if ( $6 > (1024*10)) { print $3 } }' | grep -v PID | xargs kill
PS U:\> get-process | where { $_.VS -gt 10M } | stop-process

# Powershell Sum file sizes
get-childitem | measure-object -Property length

while ( $true ) { ... }

# Powershell Switch lowercase to uppercase:

--SQLPlus formatting
column meth_spec_nm format a80;

Check for dotnet .NET Framework version
then check for a local directory like: %windir%\Microsoft.NET\Framework\<version>

-- Oracle schema info
select object_type, count(*) from dba_objects where owner='PKS_USER' group by object_type;

// Font size attributes CSS
h4 { color:#FFFF99; font-weight:bold; font-size:110%; font-style:italic; width:70%; border:1px dashed #333 }

-- Be careful with asterisks if tables aren't named identically
SELECT foo FROM tblfoo  UNION      SELECT bar FROM tblbar; -- stacks two tables and eliminates dups
SELECT foo FROM tblfoo  UNION ALL  SELECT bar FROM tblbar; -- stacks two tables and keeps dups (rare since records are then ambigous)

--delete a method from pec database table
DELETE FROM pks_extraction_control WHERE meth_spec_nm LIKE 'ATM02102%';

Excel uses exponentiation e.g. 1E+13 for large numbers - avoid by Format Cells : Custom : Enter "#" in Type field

git checkout .   # discard abandon all pending changes "not staged for commit"

xxOTHERxx END:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:

  # vim: set hlsearch foldmethod=marker tw=0 ft=CONF :