Monday, June 2, 2008

How to get last day of each month

import java.util.Calendar;

public class CalProblem
{
  public static void main(String[] args)
  {
     Calendar myCal     = Calendar.getInstance();

     myCal.set(Calendar.MONTH, 1);
     myCal.set(Calendar.YEAR, 2007);
     System.out.println("");
     System.out.println("Year               => "+myCal.get(Calendar.YEAR));
     System.out.println("Month              => "+myCal.get(Calendar.MONTH));
     System.out.println("Last Day of Month  => "+myCal.getActualMaximum(Calendar.DAY_OF_MONTH));

     myCal.set(Calendar.MONTH, 1);
     myCal.set(Calendar.YEAR, 2008);
     System.out.println("");
     System.out.println("Year               => "+myCal.get(Calendar.YEAR));
     System.out.println("Month              => "+myCal.get(Calendar.MONTH));
     System.out.println("Last Day of Month  => "+myCal.getActualMaximum(Calendar.DAY_OF_MONTH));

  }
}

Sunday, June 1, 2008

Using grep

New Linux users unfamiliar with this standard Unix tool may not
realize how useful it is. In this tutorial for the novice user, Eric
demonstrates grep techniques.

When I first started working in systems integration, I was primarily a
PC support person. I spent a lot of time installing and supporting
Windows applications in various PC LAN configurations, running various
versions (and vendors) of TCP/IP transports. Since then, I have
successfully ditched DOS and moved on. Now, after working on various
versions of Unix for a few years, I porting some of our networking and
data manipulation libraries to other platforms and environments, such
as the AS/400 minicomputer and the Macintosh. This ongoing experience
has given me a chance to appreciate just how powerful the tools we
take for granted with Linux really are.

Searching for a word (or any other value) in a group of files is a
very common task. Whether it's searching for a function in a group of
source code modules, trying to find a parameter in a set of
configuration files, or simply looking for a misplaced e-mail message,
text searching and matching operations are common in all environments.

Unfortunately, this common task doesn't have an easy solution on all
platforms. On most, the best solution available is to use the search
function in an editor. But when it comes to Linux (and other Unix
descendants), you have many solutions. One of them is grep.

grep is an acronym for "global regular expression print," a reference
to the command in the old ed line editor that prints all of the lines
in a file containing a specified sequence of characters. grep does
exactly that: it prints out lines in a file that contain a match for a
regular expression. We'll gradually delve into what a regular
expression is as we go on.
Starting Out

First, let's look at a quick example. We will search for a word in the
Configure script provided with Linux for setting up the Linux kernel
source, which is usually installed in the /usr/src/linux directory.
Change to that directory and type (the $ character is the prompt,
don't type it):

$ grep glob Configure

You should see:

# Disable filename globbing once and for all.

glob is in bold to illustrate what grep matched. grep does not
actually print matches in bold.

grep looked for the sequence of characters glob and printed the line
of the Configure file with that sequence. It did not look for the word
glob. It looked for g followed by l followed by o followed by b. This
points out one important aspect of regular expressions: they match
sequences of characters, not words.

Before we dig any deeper into the specifics of pattern matching, let's
look at grep's "user interface" with a few examples. Try the following
two commands:

$ grep glob < Configure
$ cat Configure | grep glob

both of these two commands should print

# Disable filename globbing once and for all.

which probably looks familiar.

In all of these commands, we have specified the regular expression as
the first argument to grep. With the exception of any command line
switches, grep always expects the regular expression as the first
argument.

However, we presented grep with three different situations and
received the same response. In the first exercise, we provided grep
with the name of a file, and it opened that file and searched it. grep
can also take a list of filenames to search.

In the other two exercises we illustrated a feature that grep shares
with many other utilities. If no files are specified on the command
line, grep reads standard input. To further illustrate standard input
let's try one more example:

$ grep foo

When you run that, grep appears to "hang" waiting for something. It
is. It's waiting for input. Type:

tttt

and press return. Nothing happens. Now type:

foobar

and press enter. This time, grep sees the string foo in foobar and
echos the line foobar back at you, which is why foobar appears twice.
Now type ctrl-d, the "end-of-file" character, to tell grep that it has
reached the end of the file, whereupon it exits.

You just gave grep an input file that consisted of tttt, a newline
character, foobar, a newline character, and the end-of-file character.

Piping input into grep from standard input also has another frequent
use: filtering the output of other commands. Sometimes cutting out the
unnecessary lines with grep is more convenient than reading output
page by page with more or less:

$ ps ax | grep cron

efficiently gives you the process information for crond.
Special Characters

Many Unix utilities use regular expressions to specify patterns.
Before we go into actual examples of regular expressions, let's define
a few terms and explain a few conventions that I will use in the
exercises.

*

Character any printable symbol, such as a letter, number, or
punctuation mark.
*

String a sequence of characters, such as cat or segment
(sometimes referred to as a literal).
*

Expression also a sequence of characters. The difference between
a string and an expression is that while strings are to be taken
literally, expressions must be evaluated before their actual value can
be determined. (The manual page for GNU grep compares regular
expressions to mathematical expressions.) An expression usually can
stand for more than one thing, for example the regular expression
th[ae]n can stand for then or than. Also, the shell has its own type
of expression, called globbing, which is usually used to specify file
names. For example, *.c matches any file ending in the characters .c.
*

Metacharacters the characters whose presence turns a string into
an expression. Metacharacters can be thought of as the operators that
determine how expressions are evaluated. This will become more clear
as we work through the examples below.

Interference

You have probably entered a shell command like

$ ls -l *.c

at some time. The shell "knows" that it is supposed to replace *.c
with a list of all the files in the current directory whose names end
in the characters .c.

This gets in the way if we want to pass a literal * (or ?, |, $, etc.)
character to grep. Enclosing the regular expression in `single quotes'
will prevent the shell from evaluating any of the shell's
metacharacters. When in doubt, enclose your regular expression in
single quotes.
Basic Searches

The most basic regular expression is simply a string. Therefore a
string such as foo is a regular expression that has only one match:
foo.

We'll continue our examples with another file in the same directory,
so make sure you are still in the /usr/src/linux directory:

$ grep Linus CREDITS

Linus
N: Linus Torvalds
E: Linus.Torvalds@Helsinki.FI
D: Personal information about Linus

This quite naturally gives the four lines that have Linus Torvalds'
name in them.

As I said earlier, the Unix shells have different metacharacters, and
use different kinds of expressions. The metacharacters . and * cause
the most confusion for people learning regular expression syntax after
they have been using shells (and DOS, for that matter).

In regular expressions, the character . acts very much like the ? at
the shell prompt: it matches any single character. The *, by contrast,
has quite a different meaning: it matches zero or more instances of
the previous character.

If we type

$ grep tha. CREDITS

we get this (partial listing only):

S: Northampton
E: Hein@Informatik.TU-Clausthal.de

As you can see, grep printed every instance of tha followed by any
character. Now try

$ grep 'tha*' CREDITS
S: Northampton
D: Author of serial driver
D: Author of the new e2fsck
D: Author of loopback device driver

We received a much larger response with "*". Since "*" matches zero or
more instances of the previous character (in this case the letter
"a"), we greatly increase our possibility of a match because we made
th a legal match!
Character Classes

One of the most powerful constructs available in regular expression
syntax is the character class. A character class specifies a range or
set of characters to be matched. The characters in a class are
delineated by the [ and ] symbols. The class [a-z] matches the
lowercase letters a through z, the class [a-zA-Z] matches all letters,
uppercase or lowercase, and [Lh] would match upper case L or lower
case h.

$ grep 'sm[ai]' CREDITS
E: csmith@convex.com
D: Author of several small utilities

since our expression matches sma or smi. The command

$ grep '[a-z]' CREDITS

gives us most of the file. If you look at the file closely, you'll see
that a few lines have no lowercase letters; these are the only lines
that grep does not print.

Now since we can match a set of characters, why not exclude them
instead? The circumflex, ^, when included as the first member of a
character class, matches any character except the characters specified
in the class.

$ grep Sm CREDITS

gives us three lines:

D: Small patches for kernel, libc
D: Smail binary packages for Slackware and Debian
N: Chris Smith
$ grep 'Sm[^i]' CREDITS

gives us two

D: Small patches for kernel, libc
D: Smail binary packages for Slackware and Debian

because we excluded i as a possible letter to follow Sm.

To search for a class of characters including a literal ^ character,
don't place it first in the class. To search for a class including a
literal -, place it the very last character of the class. To search
for a class including the literal character ], place it the first
character of the class.

Often it is convenient to base searches on the position of the
characters on a line. The ^ character matches the beginning of a line
(outside of a character class, of course) and the $ matches the end.
(Users of vi may recognize these metacharacters as commands.) Earlier,
searching for Linus gave us four lines. Let's change that to:

grep 'Linus$' CREDITS

which gives us

Linus
D: Personal information about Linus

two lines, since we specified that Linus must be the last five
characters of the line. Similarly,

grep - CREDITS

produces 99 lines, while

grep '^-' CREDITS

produces only one line:

----------

In some circumstances you may need to match a metacharacter. Inside a
character class set all characters are taken as literals (except ^, -,
and ], as shown above). However, outside of classes we need a way to
turn a metacharacter into a literal character to match.
Matching Metacharacters

For this purpose the special metacharacter \ is used to escape
metacharacters. Escaped metacharacters are interpreted literally, not
as a component of an expression. Therefore \[ would match any sequence
with a [ in it:

$ grep '[' CREDITS

produces an error message:

grep: Unmatched [ or [^

but

$ grep '\[' CREDITS

produces two lines:

E: hennus@sky.ow.nl [My uucp-fed Linux box at home]
D: The XFree86[tm] Project

If you need to search for a \ character, escape it just like any other
metacharacter: \\
Options

As you can see, with just its support of regular expression syntax,
grep provides us with some very powerful capabilities. Its command
line options add even more power.

Sometimes you are looking for a string, but don't know whether it is
upper, lower, or mixed case. For this situation grep offers the -i
switch. With this option, case is completely ignored:

$ grep -i lINuS CREDITS
Linus
N: Linus Torvalds
E: Linus.Torvalds@Helsinki.FI
D: Personal information about Linus

The -v option causes grep to print all lines that do not contain the
specified regular expression:

$ grep -v '^#" /etc/syslog.conf | grep -v '^$'

prints all the lines from /etc/syslog.com that are neither commented
(starting with #) nor empty (^$). This prints six lines on my system,
although my syslog.conf file really has 21 lines.

If you need to know how many lines match, pass grep the -c option.
This will output the number of matching lines (not the number of
matches; two matches in one line count as one) without printing the
lines that match:

$ grep -c Linux CREDITS
33

If you are searching for filenames that contain a given string,
instead of the actual lines that contain it, use grep's -l switch:

$ grep -l Linux *
CREDITS
README
README.modules

grep also notifies us, for each subdirectory, that it can't search
through a directory. This is normal and will happen whenever you use a
wildcard that happens to include directory names as well as file
names.

The opposite of -l is -L. This option will cause grep to return the
names of files that do not contain the specified pattern.

If you are searching for a word and want to suppress matches that are
partial words use the -w option. Without the -w option,

$ grep -c a README

tells us that it matched 146 lines, but

$ grep -wc a README

returns only 35 since we matched only the word a, not every line with
the character a.

Two more useful options:

$ grep -b Linus CREDITS
301: Linus
17446:N: Linus Torvalds
17464:E: Linus.Torvalds@Helsinki.FI
20561:D: Personal information about Linus
$ grep -n Linus CREDITS
7: Linus
793:N: Linus Torvalds
794:E: Linus.Torvalds@Helsinki.FI
924:D: Personal information about Linus

The -b option causes grep to print the byte offset (how many bytes the
match is from the beginning of the file) of each match before the
corresponding line of output. The -n switch gives the line number.
Another grep

GNU also provides egrep (enhanced grep). The regular expression syntax
supported by GNU egrep adds a few other metacharacters:

*

? Like *, except that it matches zero or one instances instead
of zero or more.
*

+ the preceding character is matched one or more times.
*

| separates regular expressions by ORing them together.

$ egrep -i 'linux|linus' CREDITS

outputs any line that contains linus or linux.

To allow for legibility, parentheses "(" and ")" can be used in
conjunction with "|" to separate and group expressions.
More Than Just grep

This covers many of the features provided by grep. If you look at the
manual page, which I strongly recommend, you will see that I did leave
out some command-line options, such as different ways to format grep's
output and a method for searching for strings without employing
regular expressions.

Learning how to use these powerful tools provides Linux users with two
very valuable advantages. The first (and most immediate) of these is a
time-saving way to process files and output from other commands.

The second is familiarity with regular expressions. Regular
expressions are used throughout the Unix world in tools such as find
and sed and languages such as awk, perl and Tcl. Learning this syntax
prepares you to use some of the most powerful computing tools
available.

A mini-tutorial on the Unix/Linux find command

Locating Files:

The find command is used to locate files on a Unix or Linux system.
find will search any set of directories you specify for files that
match the supplied search criteria. You can search for files by name,
owner, group, type, permissions, date, and other criteria. The search
is recursive in that it will search all subdirectories too. The
syntax looks like this:

find where-to-look criteria what-to-do

All arguments to find are optional, and there are defaults for all
parts. (This may depend on which version of find is used. Here we
discuss the freely available GNU version of find, which is the version
available on YborStudent.) For example where-to-look defaults to .
(that is, the current working directory), criteria defaults to none
(that is, show all files), and what-to-do (known as the find action)
defaults to -print (that is, display found files to standard output).

For example:

find

will display all files in the current directory and all
subdirectories. The commands

find . -print
find .

do the exact same thing. Here's an example find command using a
search criteria and the default action:

find / -name foo

will search the whole system for any files named foo and display them.
Here we are using the criteria -name with the argument foo to tell
find to perform a name search for the filename foo. The output might
look like this:

/home/wpollock/foo
/home/ua02/foo
/tmp/foo

If find doesn't locate any matching files, it produces no output.

The above example said to search the whole system, by specifying the
root directory (/) to search. If you don't run this command as root,
find will display a error message for each directory on which you
don't have read permission. This can be a lot of messages, and the
matching files that are found may scroll right off your screen. A
good way to deal with this problem is to redirect the error messages
so you don't have to see them at all:

find / -name foo 2>/dev/null

Other Features And Applications:

The -print action lists the files separated by a space when the output
is piped to another command. This can lead to a problem if any found
files contain spaces in their names, as the output doesn't use any
quoting. In such cases, when the output of find contains a file name
such as foo bar and is piped into another command, that command sees
two file names, not one file name containing a space.

In such cases you can specify the action -print0 instead, which lists
the found files separated not with a space, but with a null character
(which is not a legal character in Unix or Linux file names). Of
course the command that reads the output of find must be able to
handle such a list of file names. Many commands commonly used with
find (such as tar or cpio) have special options to read in file names
separated with nulls instead of spaces.

You can use shell-style wildcards in the -name search argument:

find . -name foo\*bar

This will search from the current directory down for foo*bar (that is,
any filename that begins with foo and ends with bar). Note that
wildcards in the name argument must be quoted so the shell doesn't
expand them before passing them to find. Also, unlike regular shell
wildcards, these will match leading periods in filenames. (For
example find -name \*.txt.)

You can search for other criteria beside the name. Also you can list
multiple search criteria. When you have multiple criteria any found
files must match all listed criteria. That is, there is an implied
Boolean AND operator between the listed search criteria. find also
allows OR and NOT Boolean operators, as well as grouping, to combine
search criteria in powerful ways (not shown here.)

Here's an example using two search criteria:

find / -type f -mtime -7 | xargs tar -rf weekly_incremental.tar
gzip weekly_incremental.tar

will find any regular files (i.e., not directories or other special
files) with the criteria -type f, and only those modified seven or
fewer days ago (-mtime -7). Note the use of xargs, a handy utility
that coverts a stream of input (in this case the output of find) into
command line arguments for the supplied command (in this case tar,
used to create a backup archive). 1

Another use of xargs is illustrated below. This command will
efficiently remove all files named core from your system (provided you
run the command as root of course):

find / -name core | xargs /bin/rm -f
find / -name core -exec /bin/rm -f '{}' \; # same thing
find / -name core -delete # same if using Gnu find

(The last two forms run the rm command once per file, and are not as
efficient as the first form.)

One of my favorite find criteria is to locate files modified less than
10 minutes ago. I use this right after using some system
administration tool, to learn which files got changed by that tool:

find / -mmin -10

(This search is also useful when I've downloaded some file but can't locate it.)

Another common use is to locate all files owned by a given user (-user
username). This is useful when deleting user accounts.

You can also find files with various permissions set. -perm
/permissions means to find files with any of the specified permissions
on, -perm -permissions means to find files with all of the specified
permissions on, and -perm permissions means to find files with exactly
permissions. Permisisons can be specified either symbolically
(preferred) or with an octal number. The following will locate files
that are writeable by others:

find . -perm +o=w

(Using -perm is more complex than this example shows. You should
check both the POSIX documentation for find (which explains how the
symbolic modes work) and the Gnu find man page (which describes the
Gnu extensions).

When using find to locate files for backups, it often pays to use the
-depth option, which forces the output to be depth-first—that is,
files first and then the directories containing them. This helps when
the directories have restrictive permissions, and restoring the
directory first could prevent the files from restoring at all (and
would change the time stamp on the directory in any case). Normally,
find returns the directory first, before any of the files in that
directory. This is useful when using the -prune action to prevent
find from examining any files you want to ignore:

find / -name /dev -prune | xargs tar ...

When specifying time with find options such as -mmin (minutes) or
-mtime (24 hour periods, starting from now), you can specify a number
n to mean exactly n, -n to mean less than n, and +n to mean more than
n. 2 For example:

find . -mtime 0 # find files modified within the past 24 hours
find . -mtime -1 # find files modified within the past 24 hours
find . -mtime 1 # find files modified between 24 and 48 hours ago
find . -mtime +1 # find files modified more than 48 hours ago
find . -mmin +5 -mmin -10 # find files modifed between 6 and 9 minutes ago

The following displays non-hidden (no leading dot) files in the
current directory only (no subdirectories), with an arbitrary output
format (see the man page for the dozens of possibilities with the
-printf action):

find . -maxdepth 1 -name '[!.]*' -printf 'Name: %16f Size: %6s\n'

As a system administrator you can use find to locate suspicious files
(e.g., world writable files, files with no valid owner and/or group,
SetUID files, files with unusual permissions, sizes, names, or dates).
Here's a final more complex example (which I save as a shell script):

find / -noleaf -wholename '/proc' -prune \
-o -wholename '/sys' -prune \
-o -wholename '/dev' -prune \
-o -wholename '/windows-C-Drive' -prune \
-o -perm -2 ! -type l ! -type s \
! \( -type d -perm -1000 \) -print

This says to seach the whole system, skipping the directories /proc,
/sys, /dev, and /windows-C-Drive (presumably a Windows partition on a
dual-booted computer). The -noleaf option tells find to not assume
all remaining mounted filesystems are Unix file systems (you might
have a mounted CD for instance). The -o is the Boolean OR operator,
and ! is the Boolean NOT operator (applies to the following criteria).
So this criteria says to locate files that are world writable (-perm
-2) and NOT symlinks (! -type l) and NOT sockets (! -type s) and NOT
directories with the sticky (or text) bit set (! \( -type d -perm
-1000 \)). (Symlinks, sockets and directories with the sticky bit set
are often world-writable and generally not suspicious.)

A common request is a way to find all the hard links to some file.
Using ls -li file will tell you how many hard links the file has, and
the inode number. You can locate all pathnames to this file with:

find mount-point -xdev -inum inode-number

Since hard links are restricted to a single filesystem, you need to
search that whole filesystem so you start the search at the
filesystem's mount point. (This is likely to be either /home or / for
files in your home directory.) The -xdev options tells find to not
search any other filesystems.

(While most Unix and all Linux systems have a find command that
supports the -inum criteria, this isn't POSIX standard. Older Unix
systems provided the ncheck command instead that could be used for
this.)
Using -exec Efficiently

The -exec option to find is great, but since it runs the command
listed for every found file, it isn't very efficient. On a large
system this makes a difference! One solution is to combine find with
xargs as discussed above:

find whatever... | xargs command

However this approach has two limitations. Firstly not all commands
accept the list of files at the end of the command. A good example is
cp:

find . -name \*.txt | xargs cp /tmp # This won't work!

(Note the Gnu version of cp has a non-POSIX option -t for this.)

Secondly filenames may contain spaces or newlines, which would confuse
the command used with xargs. (Again Gnu tools have options for that,
find ... -print0 |xargs -0 ....)

There are POSIX (but non-obvious) solutions to both problems. An
alternate form of -exec ends with a plus-sign, not a semi-colon. This
form collects the filenames into groups or sets, and runs the command
once per set. (This is exactly what xargs does, to prevent argument
lists from becoming too long for the system to handle.) In this form
the {} argument expands to the set of filenames. For example:

find / -name core -exec /bin/rm -f '{}' +

This form of -exec can be combined with a shell feature to solve the
other problem. The POSIX shell allows us to use:

sh -c 'command-line' [ command-name [ args... ] ]

(We don't usually care about the command-name, so X, dummy, or inline
cmd is used.) Here's an example of efficiently copying found files,
in a POSIX-compliant way 3:

find . -name '*.txt' -exec sh -c 'cp "$@" /tmp' dummy {} +

Or even better:

find . -name '*.txt' -type f \
-exec sh -c 'exec cp -f "$@" /tmp' find-copy {} +

The find command can be amazingly useful. See the man page to learn
all the criteria and options you can use.

Google+