Thursday, June 18, 2009

using find to catch up on what's changed

I came back from a two week vacation and needed to find out what had been updated/added/changed in that time in some shared project dirs. "find" was my friend. The following command gives a list of all files changed within the last two weeks.

find . -ctime -14
'-ctime -14' will be true for all files/dirs that have been changed in the last 14*24 hours. You can alter the behaviour by changing the modifier on the numerical input:

+n for greater than n,
-n for less than n,
n for exactly n.

Monday, May 18, 2009

jvisualvm instead of kill -3

Whenever I need to see what's going on under the hood of a process I issue a kill -3 to get a stack-trace. Well, I was just introduced to jvisualvm! This is a great way to see what's going on with a running java process.

Changing the mysql prompt

This is such an obvious thing to do, why didn't I do it before?

I'm constantly jumping into and between multiple databases as multiple users (test, standard, mysql) it becomes a little dangerous and I'm finding myself checking where I am and who I am:
SELECT user();
SELECT database();

but you can change the standard mysql prompt to display the user and database! Just edit the my.cnf file and place the following under [mysql]:

prompt=\\u@\\d:

Now my prompt looks like this:
paul@test:
or
root@main:

If you don't have permissions to alter the my.cnf directly, then you could change your personal .bashrc (or equivalent) to contain something like this:

alias mysql='mysql --prompt="\u@\d:"'

This has saved me a lot of paranoia (and probably some headaches).

Friday, May 1, 2009

bash substring substitution

I just came across this today, it's something that I wish I'd known years ago (I think it just shows that I need to read more manuals), I've been emulating this feature with Perl and regexes or with the basename/dirname commands.

It's very simple; today I wanted to run through a set of files with a particular file extension, do some processing and then print the output to another file named the same as the original but with a different extension.

So, say the files are .tsv (tab delimited) and I want to create a .csv (comma delimited) one from the first two columns, you can do it like this:


for file in `ls *.tsv`;
do cut -f1,2 --output-delimiter=, \
$file > ${file/.tsv/.csv};
done
Sweet, eh?

Friday, April 24, 2009

Histograms in gnuplot

I'm pretty new to gnuplot, but have found it to be a handy tool for simple plots.  

Today I needed to generate a simple histogram.  Rather than creating a permanent script I've just been piping a string into gnuplot from echo.

echo "set terminal png;\
set output 'timings.png';\
set style fill solid 0.5 border -1;\
set xlabel 'chunks';\
set ylabel 'time to complete (m)';\
set key autotitle columnhead;\
set title 'timings on 20 nodes';\
set auto x;\
plot 'timings.tsv' u 2:xticlabels(1) with boxes lt 2;"\
|  gnuplot


and out pops a nice histogram (sorry, can't post this example as it's work related).

The input file had column headers and the first column was used as the xlabels (see the xticlabels call above?)

Thursday, April 23, 2009

Stacktrace from a running process

There have been a few occasions where I've been very confused as to why a process is taking a long time to run (usualy Java processes).  It's often handy to request a stacktrace from the running process; you can do this without terminating it by issuing 'kill -3 <pid>'.   Good, eh?

Unix Join with tabs

This one had me scratching my head for a while yesterday.  When you use the unix 'join' command with the default separators (whitespace) then you can join tab delimited files, but the output is space delimited.

I tried specifying the join character with -t "\t" or -t '\t' and even the despearate -t\t, but none of that works.  Turns out you have to use an *actual* quoted tab character (which I found through a quick google search, the solution was here, thank you JJinuxLand).  

You can insert a tab on the command line with the following key combo "ctrl-v <tab>".

Update: the easier way of doing this is to use the special quoting construct $'string' e.g. join -t $'\t'
See the "QUOTING" section of the bash man page for details.