Finding Memory leaks in C++ on solaris Unix

There are lot of ways where one can identify memory leaks and lots of blogs and materieals
are available to help a designer to identify the same.

Some say using dbx and others say use mdb or gdb. I agree that all those tools will be useful, but it takes a lot of effort for understanding as well as putting it to work takes some time.

I have thought to break the legacy rules and do something new with the knowledge that
I have on various tools of solaris. So I thought of giving it a try to use tools like
dtrace, perl, ps command etc along with c++.

Putting this toll to action is an effort less job.

I am happy to have created a tool which I think would be very use for any solaris unix programmer.
This tool will give the list of all memory leaks of a process running in the background.

It uses dtrace to identify the memory allocations,
It uses the ps command to identify the memory used by a process.
It uses perl to filter and generate reports of meory leaks.

Main functionalities of this tool are:

  • Generate a report which contains actual physical memory used by the process, Virtual memory used, % of cpu used and %memory used.
  • Generate a report which contains all the memory leaks of the process due to inefficient coding techniques.
  • Generate a separate report for each and every process.

I have tested this on:
SunOS 5.10 Generic_147440-27 sun4u sparc SUNW,SPARC-Enterprise

Thanks to Frederic, I have taken part of his logic written in his blog:

You can download the zip file from the link here:

The file name is cpuleaks.gz.
Unzip this file using gzip -d cpuleaks.gz and you can place it on any server and give the execute permissions and run this process as a root user(dtrace can be run only using root access on my server. If dtrace can be used by a user other than root, well and fine).

Execution of the process should be as below:
 

cpuleaks <comma separated pid list> -st <time interval for mem usage>
 
ex: cpuleaks 1234,2341 -st 2

This above command will give 4 files as output after either the processes 1234,2341 complete or if you press CTRL +C(an interrupt signal).
1234.cpumem
1234.leaks
2341.cpumem
2341.leaks

 
where
  • .leaks report will have the list of all memory leaks
  • .cpumem report will have the memory usage of the process for every interval passed as an argument to the cpuleaks binary.

2 comments:

Search Multiple strings and print them in the order of search strings

Thursday, September 05, 2013 , 0 Comments

One of my colleagues asked this query to me. And I liked the query very much.
So I started thinking about that.
For example i have a below file:
1 name1
2 name2
3 name3
4 name1
5 name4
6 name2
7 name1
Now i want to find strings in the file , lets say in the order name1, name2, name3, name4.
And i also want the output to be in the same order in the way i searched as below:
1 name1
4 name1
7 name1
2 name2
6 name2
3 name3
5 name4
Obviously we cannot do this with a single grep command without any temporary files being created.
So I thought perl would be a better option for this. So I came up with a simple perl solution.
perl -lne '/name1/?push @a,$_:
          (/name2/?push @b,$_:
          (/name3/?push @c,$_:
           /name4/?push @d,$_:next));
          END{print join "\n",@a,@b,@c,@d}' your_file

And this worked like a a charm.

0 comments:

Some Useful Perl one liner's

Monday, September 02, 2013 , 0 Comments

We'll start with a brief refresher on the basics of perl one-liners before we begin. The core of any perl one-liner is the -e switch, which lets you pass a snippet of code on the command-line:perl -e 'print "hi\n"' prints "hi" to the console.
The second standard trick to perl one-liners are the -n and -p flags. Both of these make perl put an implicit loop around your program, running it once for each line of input, with the line in the $_ variable. -p also adds an implicit print at the end of each iteration.
Both of these use perl's special "ARGV" magic file handle internally. What this means is that if there are any files listed on the command-line after your -e, perl will loop over the contents of the files, one at a time. If there aren't any, it will fall back to looping over standard input.
perl -ne 'print if /foo/'
acts a lot like grep foo, and
perl -pe 's/foo/bar/'
replaces foo with bar
Most of the rest of these tricks assume you're using either -n or -p, so I won't mention it every time.

The top 10 one-liner tricks

One Liner-1:   -l
Smart newline processing. Normally, perl hands you entire lines, including a trailing newline. With -l, it will strip the trailing newline off of any lines read, and automatically add a newline to anything you print (including via -p).
Suppose I wanted to strip trailing whitespace from a file. I might naïvely try something like
perl -pe 's/\s*$//'
The problem, however, is that the line ends with "\n", which is whitespace, and so that snippet will also remove all newlines from my file! -l solves the problem, by pulling off the newline before handing my script the line, and then tacking a new one on afterwards:
perl -lpe 's/\s*$//'

One Liner-2: -0
Occasionally, it's useful to run a script over an entire file, or over larger chunks at once. -0 makes -n and -p feed you chunks split on NULL bytes instead of newlines. This is often useful for, e.g. processing the output of find -print0. Furthermore, perl -0777 makes perl not do any splitting, and pass entire files to your script in $_.
find . -name '*~' -print0 | perl -0ne unlink
Could be used to delete all ~-files in a directory tree, without having to remember how xargs works.
One Liner-3: -i
-i tells perl to operate on files in-place. If you use -n or -p with -i, and you pass perl filenames on the command-line, perl will run your script on those files, and then replace their contents with the output. -i optionally accepts an backup suffix as argument; Perl will write backup copies of edited files to names with that suffix added.
perl -i.bak -ne 'print unless /^#/' script.sh
Would strip all whole-line commands from script.sh, but leave a copy of the original in script.sh.bak.
One Liner-4: The .. operator
Perl's .. operator is a stateful operator -- it remembers state between evaluations. As long as its left operand is false, it returns false; Once the left hand returns true, it starts evaluating the right-hand operand until that becomes true, at which point, on the next iteration it resets to false and starts testing the other operand again.
What does that mean in practice? It's a range operator: It can be easily used to act on a range of lines in a file. For instance, I can extract all GPG public keys from a file using:
perl -ne 
                       'print 
                        if /-----BEGIN PGP PUBLIC KEY BLOCK-----/
                        ..
                        /-----END PGP PUBLIC KEY BLOCK-----/
                       ' FILE
One Liner-5: -a
-a turns on autosplit mode – perl will automatically split input lines on whitespace into the @F array. If you ever run into any advice that accidentally escaped from 1980 telling you to use awk because it automatically splits lines into fields, this is how you use perl to do the same thing without learning another, even worse, language.
As an example, you could print a list of files along with their link counts using
ls -l | perl -lane 'print "$F[7] $F[1]"'

One Liner-6: -F
-F is used in conjunction with -a, to choose the delimiter on which to split lines. To print every user in /etc/passwd (which is colon-separated with the user in the first column), we could do:
perl -F: -lane 'print $F[0]' /etc/passwd
One Liner-7: \K
\K is undoubtedly my favorite little-known-feature of Perl regular expressions. If \K appears in a regex, it causes the regex matcher to drop everything before that point from the internal record of "Which string did this regex match?". This is most useful in conjunction with s///, where it gives you a simple way to match a long expression, but only replace a suffix of it.
Suppose I want to replace the From: field in an email. We could write something like
perl -lape 's/(^From:).*/$1 Nelson Elhage <nelhage\@ksplice.com>/'
But having to parenthesize the right bit and include the $1 is annoying and error-prone. We can simplify the regex by using \K to tell perl we won't want to replace the start of the match:
perl -lape 's/^From:\K.*/ Nelson Elhage <nelhage\@ksplice.com>/'
One Liner-8: $ENV{}
When you're writing a one-liner using -e in the shell, you generally want to quote it with ', so that dollar signs inside the one-liner aren't expanded by the shell. But that makes it annoying to use a ' inside your one-liner, since you can't escape a single quote inside of single quotes, in the shell.
Let's suppose we wanted to print the username of anyone in /etc/passwd whose name included an apostrophe. One option would be to use a standard shell-quoting trick to include the ':
perl -F: -lane 'print $F[0] if $F[4] =~ /'"'"'/' /etc/passwd
But counting apostrophes and backslashes gets old fast. A better option, in my opinion, is to use the environment to pass the regex into perl, which lets you dodge a layer of parsing entirely:
env re="'" perl -F: -lane 'print $F[0] if $F[4] =~ /$ENV{re}/' /etc/passwd
We use the env command to place the regex in a variable called re, which we can then refer to from the perl script through the %ENV hash. This way is slightly longer, but I find the savings in counting backslashes or quotes to be worth it, especially if you need to end up embedding strings with more than a single metacharacter.
One Liner-9: BEGIN and END
BEGIN { ... } and END { ... } let you put code that gets run entirely before or after the loop over the lines.
For example, I could sum the values in the second column of a CSV file using:
perl -F, -lane '$t += $F[1]; END { print $t }'
One Liner-10: -MRegexp::Common
Using -M on the command line tells perl to load the given module before running your code. There are thousands of modules available on CPAN, numerous of them potentially useful in one-liners, but one of my favorite for one-liner use is Regexp::Common, which, as its name suggests, contains regular expressions to match numerous commonly-used pieces of data.
The full set of regexes available in Regexp::Common is available in its documentation, but here's an example of where I might use it:
Neither the ifconfig nor the ip tool that is supposed to replace it provide, as far as I know, an easy way of extracting information for use by scripts. The ifdata program provides such an interface, but isn't installed everywhere. Using perl and Regexp::Common, however, we can do a pretty decent job of extracing an IP from ip's output:
ip address list eth0 | \
  perl -MRegexp::Common -lne 
  'print $1 if /($RE{net}{IPv4})/'
So, those are my favorite tricks, but I always love learning more. What tricks have you found or invented for messing with perl on the command-line? What's the most egregious perl "one-liner" you've wielded, continuing to tack on statements well after the point where you should have dropped your code into a real script?

0 comments:

What is Undefined Behavior?

Tuesday, July 09, 2013 , 0 Comments

In computer programming, undefined behavior refers to computer code whose behavior is unpredictable. It is a feature of some programming languages—most famously C.[1] In these languages, to simplify the specification and allow some flexibility in implementation, the specification leaves the results of certain operations specifically undefined, meaning that the programmer can't predict what will happen.

For example, in C the use of any automatic variable before it has been initialized yields undefined behavior, as would division by zero or indexing an array outside of its defined bounds (see buffer overflow). This specifically frees the compiler to do whatever is easiest or most efficient, should such a program be submitted. In general, any behavior afterwards is also undefined. In particular, it is never required that the compiler diagnose undefined behavior — therefore, programs invoking undefined behavior may appear to compile and even run without errors at first, only to fail on another system, or even on another date. When an instance of undefined behavior occurs, so far as the language specification is concerned anything could happen, maybe nothing at all. In particular, anything may include apparently-impossible behavior because the compiler has made assumptions that lead to erroneous code generation that does not match the source code.

Under some circumstances there can be specific restrictions on undefined behavior. For example, the instruction set specifications of a CPU might leave the behavior of some forms of an instruction undefined, but if the CPU supports memory protection then the specification will probably include a blanket rule stating that no user-accessible instruction may cause a hole in the operating system's security; so an actual CPU would be permitted to corrupt any or all user registers in response to such an instruction but would not be allowed to, for example, switch into supervisor mode.
In C and C++, implementation-defined behavior is also defined which requires the implementation to document what it does, thus more restrictive than undefined behavior.

Examples in C and C++ :

Attempting to modify a string literal causes undefined behavior:[2]
char * p = "wikipedia"; // ill-formed C++11, deprecated C++98/C++03
p[0] = 'W'; // undefined behaviour
One way to prevent this is defining it as an array instead of a pointer.
char p[] = "wikipedia"; /* RIGHT */
p[0] = 'W';
In C++ one can use STL string as follows.
std::string s = "wikipedia"; /* RIGHT */
s[0] = 'W';
Division by zero results in undefined behavior:[3]
return x/0; // undefined behavior
Certain pointer operations may result in undefined behavior:[4]
int arr[4] = {0, 1, 2, 3};
int* p = arr + 5;  // undefined behavior
Reaching the end of a value-returning function (other than main()) without a return statement may result in undefined behavior:
int f()
{
}  /* undefined behavior */
The C Programming Language cites the following examples of code that have undefined behavior in Section 2.12: The order in which function arguments are evaluated is not specified, so the statement
printf("%d %d\n", ++n, power(2, n));    /* WRONG */
results in undefined behavior. The following statement is ambiguous as it is not clear whether the array index is the old value of i or the new.
a[i] = i++;
This results in undefined behavior.

0 comments:

Fork in C

Thursday, July 04, 2013 , 2 Comments

Did you try this program:

#include &ltstdio.h&gt
#include &ltsys/types.h&gt
#include &ltunistd.h&gt
int main(void)
{    
int i;    
      for(i = 0; i < 2; i++)    
      {        
        fork();        
        printf(".");    
       }    
return 0;
}

How many dots will this program print.
If you analyse and count , you will come up with a total of 6 dots.
But in real after you execute you will see not 6 but 8 dots printed on the console.

The reason for this is :
So, at first, there is one process. That creates a second process, both of which print a dot and loop. On their second iteration, each creates another copy, so there are four processes print a dot, and then exit. So we can easily account for six dots, like you expect.

However, what printf() really does is buffer its output. So the first dot from when there were only two processes does not appear when written. Those dots remain in the buffer—which is duplicated at fork(). It is not until the process is about to exit that the buffered dot appears. Four processes printing a buffered dot, plus the new one gives 8 dots.

If you wanted to avoid that behavior, call fflush(stdout); after printf().

2 comments:

Removal of unnecessary white spaces

Thursday, June 20, 2013 , 1 Comments

I have a text file which looks something like this:
1, 2, 3, "Test, Hello"
4, 5, 6, "Well, Hi There!"
You can see that there is a space after comma(,) which i feel its not needed for me. But I need that space in between the string in last field. So the output I am expecting is :
1,2,3,"Test, Hello"
4,5,6,"Well, Hi There!"
I used the below command for doing the same:
perl -lne 'if(/(.*?\")(.*)/)
          {$b=$2;$a=$1;$a=~s/,[\s]/,/g;
           print "$a$b"}' your_file
explanation:
(.*?\")(.*)
capture thye string till " in $1 and and remaining in $2.
$2 should be obviously unchanged. so store it in $b
$1 should be changed . so store it in $a and replace all ", " with ",".

Same thing can be achieved in awk as below:
nawk -F'\"' -v OFS='\"' '{gsub(/ /,"",$1)}1' your_file

1 comments:

Replace last occurrence of a string

Monday, June 17, 2013 0 Comments

How do you replace  instances of a string only in the line where they last occured.
for example if you have a file like below:
a
b
c
a
d
The output should look like below:
a
b
c
x
d
Below is the perl command that will perform the same:
perl -e '@a=reverse<>;
         END{
            for(@a){
             if(/a/){s/a/c/;last}
             }
            print reverse @a}' your_file

0 comments:

Auto in C++ - Basics

Friday, June 07, 2013 , 0 Comments

The auto Keyword: The Basics
Consider the following code snippet:
std::vector<int> vect;
// ...

for(
  std::vector<int>::const_iterator cit = vect.begin();
  cit != vect.end();
  ++cit
  )
{
  std::cout << *cit;
}
Perfectly fine, we all write code like this or similar all the time. Now let us consider this instead:
std::vector<int> vect;
// ...

for(
  std::vector<int>::iterator it = vect.begin();
  it != vect.end();
  ++it
  )
{
  std::cin >> *it;
}
When writing this code, you should be getting slightly annoyed. The variable it is of the exact same type as the expression vect.begin() with which it is being initialized, and the compiler knows what that type is. Therefore, for us to have to write std::vector<int>::iterator is redundant. The compiler should use this as the default for the type of the variable it. And that is exactly the issue that the auto keyword addresses. In C++11, we can write:
std::vector<int> vect;
// ...

for(auto it = vect.begin(); it != vect.end(); ++it)
{
  std::cin >> *it;
}
The compiler will use the type of the initializing expression vect.begin(), which is std::vector<int>::iterator, as the type of the variable it. This sounds easy enough, but it's not quite the full story on auto. Read on.
The auto Keyword: The Rest of the Story
Consider this example of using auto:
int x = int(); // x is an int, initialized to 0
assert(x == 0);

const int& crx = x; // crx is a const int& that refers to x
x = 42;
assert(crx == 42 && x == 42);

auto something = crx;
The crucial question is, what is the type of something? Since the declared type of crx is const int&, and the initializing expression for something is crx, you might think that the type of something is const int&. Not so. It turns out that the type of something is int:
assert(something == 42 && crx == 42 && x == 42);
// something is not const:
something = 43;
// something is not a reference to x:
assert(something == 43 && crx == 42 && x == 42);
Before we discuss the rationale behind this behavior, let us state the exact rules by which autoinfers the type from an initializing expression:

When auto sets the type of a declared variable from its initializing expression, it proceeds as follows:
  1. If the initializing expression is a reference, the reference is ignored.
  2. If, after Step 1 has been performed, there is a top-level const and/or volatile qualifier, it is ignored.

As you have probably noticed, the rules above look like the ones that function templates use to deduce the type of a template argument from the corresponding function argument. There is actually a small difference:auto can deduce the type std::initializer_list from a C++11-style braced list of values, whereas function template argument deduction cannot. Therefore, you may use the rule "auto works like function template argument deduction" as a first intuition and a mnemonic device, but you need to remember that it is not quite accurate.Continuing with the example above, suppose we pass the const int& variable crx to a function template:
template<class T>
void foo(T arg);
foo(crx);
Then the template argument T resolves to int, not to const int&. So for this instantiation of foo, the argument arg is of type int, not const int&. If you want the argument arg of foo to be a const int&, you can achieve that either by specifying the template argument at the call site, like this:
foo<const int&>(crx);
or by declaring the function like this:
template<class T>
void foo(const T& arg);
The latter option works analogously with auto:
const auto& some_other_thing = crx;
Now some_other_thing is a const int&, and that is of course true regardless of whether the initializing expression is an int, an int&, a const int, or a const int&.
assert(some_other_thing == 42 && crx == 42 && x == 42);
some_other_thing = 43;  // error, some_other_thing is const
x = 43;
assert(some_other_thing == 43 && crx == 43 && x == 43);
The possibility of adding a reference to the auto keyword as shown in the example above requires a small amendment to auto's const-stripping behavior. Consider this example:
  const int c = 0;
  auto& rc = c;
  rc = 44; // error: const qualifier was not removed
If you went strictly by the rules stated earlier, auto would first strip the const qualifier off the type of c, and then the reference would be added. But that would give us a non-const reference to the const variable c, enabling us to modify c. Therefore, auto refrains from stripping the const qualifier in this situation. This is of course no different from what function template argument deduction does.
Let's do one more example to demonstrate that auto drops const and volatilequalifiers only if they're at the top or right below an outermost reference:
int x = 42;
const int* p1 = &x;
auto p2 = p1;
*p2 = 43; // error: p2 is const int*
Now that we know how auto works, let's discuss the rationale behind the design. There is probably more than one way to argue. Here's my way to see why the behavior is plausible: being a reference is not so much a type characteristic as it is a behavioral characteristic of a variable. The fact that the expression from which I initialize a new variable behaves like a reference does not imply that I want my new variable to behave like a reference as well. Similar reasoning can be applied to constness and volatility1. Therefore,auto does not automatically transfer these characteristics from the initializing expression to my new variable. I have the option to give these characteristics to my new variable, by using syntax like const auto&, but it does not happen by default.

0 comments:

Range of lines from a file

Wednesday, June 05, 2013 , 0 Comments

Below is the command to extract certain lines in Perl based on line numbers.
for eg: If I need to extract lines 5 -10 then i need to do:
perl -lne 'print if($.>=5&&$.<=10) your_file

Also this can done in awk  in a much simpler way:
awk 'NR>=5&&NR<=10 your_file

Classic way of doing this is :
head -10 your_file | tail -6

0 comments:

Copy multiple files with same name from different directories

Thursday, May 30, 2013 , , , , 1 Comments

I regularly do this. So I automated it.
Below is a small simple script for copying files which are present in two different directories but without same names into a single directory with having name collision.

#!/usr/bin/sh

for i in `find <source_dir_path> -type f`
do
new=`echo $i|nawk -F"/" '{split($NF,a,".");print "<target_dir_path>"a[1]"_"$(NF-1)"."a[2]}'`
cp $i $new
done

1 comments:

Pattern Match Using Perl-Append file contents

Wednesday, May 29, 2013 , 0 Comments

If i want to append all the lines of one file  to a line in second file only if there is a pattern match:

For example:
first_file.txt:
111111
1111
11
1

second_file.txt:

122221
2222
22
2

pattern to match:

2222
output:

122221
111111
1111
11
1
2222
111111
1111
11
1
22
2

Below is the perl command to achieve this:

perl -lne 'BEGIN{open(A,"first_file.txt");@f=<A>}
           print;if(/2222/){print @f}' 
           second_file.txt

0 comments:

Retrieving a List of files from Remote Server

Friday, May 17, 2013 , 0 Comments

Below is the perl script for retrieving the list of files from Remote server:

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Net::FTP;
    my $ftp_site     = 'localhost';
    my $ftp_dir      = '/home/simon/software';
    my $ftp_user     = 'a_login_name';
    my $ftp_password = 'a_password';
    my $glob         = 'ex*';
    my @remote_files;
    my $ftp = Net::FTP-&gt;new($ftp_site)
        or die "Could not connect to $ftp_site: $!";
    $ftp-&gt;login($ftp_user, $ftp_password)
        or die "Could not login to $ftp_site with user $ftp_user: $!";
    $ftp-&gt;cwd($ftp_dir)
        or die "Could not change remote working " .
                 "directory to $ftp_dir on $ftp_site";
    @remote_files = $ftp-&gt;ls($glob);
    foreach my $file (@remote_files) {
        print "Saw: $file\n";
    }
    $ftp-&gt;quit();

0 comments:

List of Bash Conditional statements

Wednesday, May 15, 2013 , 2 Comments

At times you need to specify different courses of action to be taken in a shell script, depending on the success or failure of a command. The if construction allows you to specify such conditions.

The most compact syntax of the if command is:
if TEST-COMMANDS; then CONSEQUENT-COMMANDS; fi

The TEST-COMMAND list is executed, and if its return status is zero, the CONSEQUENT-COMMANDS list is executed. The return status is the exit status of the last command executed, or zero if no condition tested true.
The TEST-COMMAND often involves numerical or string comparison tests, but it can also be any command that returns a status of zero when it succeeds and some other status when it fails. Unary expressions are often used to examine the status of a file. If the FILE argument to one of the primaries is of the form /dev/fd/N, then file descriptor "N" is checked. stdin, stdout and stderr and their respective file descriptors may also be used for tests.

Expressions used with if
The table below contains an overview of the so-called "primaries" that make up the TEST-COMMAND command or list of commands. These primaries are put between square brackets to indicate the test of a conditional expression.

Primary expressions
[ -a FILE ] True if FILE exists.
[ -b FILE ] True if FILE exists and is a block-special file.
[ -c FILE ] True if FILE exists and is a character-special file.
[ -d FILE ] True if FILE exists and is a directory.
[ -e FILE ] True if FILE exists.
[ -f FILE ] True if FILE exists and is a regular file.
[ -g FILE ] True if FILE exists and its SGID bit is set.
[ -h FILE ] True if FILE exists and is a symbolic link.
[ -k FILE ] True if FILE exists and its sticky bit is set.
[ -p FILE ] True if FILE exists and is a named pipe (FIFO).
[ -r FILE ] True if FILE exists and is readable.
[ -s FILE ] True if FILE exists and has a size greater than zero.
[ -t FD ]   True if file descriptor FD is open and refers to a terminal.
[ -u FILE ] True if FILE exists and its SUID (set user ID) bit is set.
[ -w FILE ] True if FILE exists and is writable.
[ -x FILE ] True if FILE exists and is executable.
[ -O FILE ] True if FILE exists and is owned by the effective user ID.
[ -G FILE ] True if FILE exists and is owned by the effective group ID.
[ -L FILE ] True if FILE exists and is a symbolic link.
[ -N FILE ] True if FILE exists and has been modified since it was last read.
[ -S FILE ] True if FILE exists and is a socket.
[ FILE1 -nt FILE2 ] True if FILE1 has been changed more recently than FILE2, or if FILE1 exists and FILE2 does not.
[ FILE1 -ot FILE2 ] True if FILE1 is older than FILE2, or is FILE2 exists and FILE1 does not.
[ FILE1 -ef FILE2 ] True if FILE1 and FILE2 refer to the same device and inode numbers.
[ -o OPTIONNAME ] True if shell option "OPTIONNAME" is enabled.
[ -z STRING ] True of the length if "STRING" is zero.
[ -n STRING ] or [ STRING ] True if the length of "STRING" is non-zero.
[ STRING1 == STRING2 ]  True if the strings are equal. "=" may be used instead of "==" for strict POSIX compliance.
[ STRING1 != STRING2 ]  True if the strings are not equal.
[ STRING1 < STRING2 ]  True if "STRING1" sorts before "STRING2" lexicographically in the current locale.
[ STRING1 > STRING2 ]  True if "STRING1" sorts after "STRING2" lexicographically in the current locale.
[ ARG1 OP ARG2 ] "OP" is one of -eq, -ne, -lt, -le, -gt or -ge. These arithmetic binary operators return true if "ARG1" is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to "ARG2", respectively. "ARG1" and "ARG2" are integers.
Expressions may be combined using the following operators, listed in decreasing order of precedence:
Combining expressions
[ ! EXPR ]          True if EXPR is false.
[ ( EXPR ) ]        Returns the value of EXPR. This may be used to override the normal precedence of operators.
[ EXPR1 -a EXPR2 ]  True if both EXPR1 and EXPR2 are true.
[ EXPR1 -o EXPR2 ]  True if either EXPR1 or EXPR2 is true.

The [ (or test) built-in evaluates conditional expressions using a set of rules based on the number of arguments. More information about this subject can be found in the Bash documentation. Just like the if is closed with fi, the opening square bracket should be closed after the conditions have been listed.

2 comments:

Semicolon and Perl

Monday, May 13, 2013 , 0 Comments

I guess most of the people have noticed about this and have just ignored it. Or they must not have noticed it at all. Do you know this fact about perl:
If you write this :
for(@arr) { print $_ }
Its not an error in Perl. According to Perldoc:
Every simple statement must be terminated with a semicolon, unless it is the final statement in a block, in which case the semicolon is optional.

0 comments:

Row width and Column separator in Sybase isql

Thursday, May 09, 2013 , 0 Comments

Many of you either donot know or perhaps you are not aware of these since there is very less documentation available in google search for these

In general I use:
isql -U<user> -P<passsword>  -D<dbname>

There are two ioptions in isql.
which are
-s     Column separator.This wil separate columns with what ever character is followed by this option
       another option is (and probably very important):
-w     This will set the row width.By default is set to 80 characters and if the row length exceeds 80          
       characters, a new line is added in the console output.
for eg:
isql -U<user> -P<passsword>  -D<dbname> -s ',' -w 65535

0 comments:

Consequetive pattern match in Perl

Tuesday, May 07, 2013 , 0 Comments

Make a pattern that will match three consecutive copies of whatever is currently contained in $what. That is, if
$what="fred" , your pattern should match "fredfredfred".
If
$what is "fred|barney", your pattern should match
"fredfredbarney" and
"barneyfredfred" and
"barneybarneybarney" and  many other variations.
Well, This is quite tricky. But the magic match to do over here is :
/($str){3}/

 Below is the example code:
#!/usr/bin/perl
use warnings;
use strict;
# notice the example has the `|`. Meaning
# match "fred" or "barney" 3 times.
my $str = 'fred|barney';
my @tests = qw(fred fredfredfred barney barneybarneybarny barneyfredbarney);
for my $test (@tests) {
if( $test =~ /^($str){3}$/ ) {
print "$test matched!\n";
} else {
print "$test did not match!\n";
}
}

Below is the execution:
> ./temp9.pl
fred did not match!
fredfredfred matched!
barney did not match!
barneybarneybarny did not match!
barneyfredbarney matched!

0 comments:

How does free work in C

Thursday, May 02, 2013 , , , 0 Comments

This is very important for every C/C++ programmer to know. And most of the interviewers too ask this question.I myself had asked in many interviews, but hardly I can get a good response from the people. So I thought it would be better to post it here so that people will get to know.
char *ptr =malloc(5*sizeof(char));
The above statement will allocate 5 bytes of memory for the pointer ptr on HEAP. Most of the people that I came across specially graduates think that memory is allocated on stack which is actually not true.

So after you use ptr in your code and get the task done you have to delete or free the memory.so you write this for it.
free(ptr);
Remember, you are not passing 5 bytes to free as an argument, but how come free function know that it has to free 5 bytes? When you call malloc(), you specify the amount of memory to allocate. The amount of memory actually used is slightly more than this, and includes extra information that records (at least) how big the block is. You can't (reliably) access that other information - and nor should you . When you call free(), it simply looks at the extra information to find out how big the block is.

This is the logic behind this magic(at least for a programmer this is a magic provided by the standard).
also see the link in c-faqs:
How does free know how many bytes to free?
Same principle is followed for delete and new.

0 comments:

Replace a string with an environment variable.

Tuesday, April 30, 2013 1 Comments

Many times its required inside a shell script that you need to replace a string in a file with a value which is present in a environment variable.Most of the time people will face this in their daily work life if they work on unix exclusively.
Below is the way to do it.
echo $LINE | sed -e "s/12345678/${replace}/g"
Small test below:
export replace=987654321
echo X123456789X | sed "s/123456789/${replace}/"
X987654321X

1 comments:

Hiding a standard library function in c++

Thursday, April 25, 2013 , 0 Comments

I have a function abs in one of the libraries and I wanted to use that function by linking to that library.But I am facing this error below:
function abs used is #define abs(x) (x &gt; 0) ? x : -(x).
This is obviously from the standard includes that I used. So I found a some very nice ways to overcome this problem :

  • Wrapping the function name abs in parenthesis has resolved the problem right away.
    (abs)(arguments)

  • Using the preprocessor directives Before you call the function abc in the library.
    #undef abs


0 comments:

Print Lines having unique fields

Tuesday, April 23, 2013 0 Comments

I have a table in which most of the values in a given row are the same. What I want to pull out are any rows where at least one of the values is different.
For example I have a file:
one one one one two
two two two two two
three four four five
I found a nice trick for doing this:
awk '{f=$0;gsub($1,"")}NF{print f}' file
one one one one two
three four four five
First we store the line in original state f=$0 then we do a global substitution on everything matching the first field, if all fields are the same then nothing will be left therefor NF will be 0 and nothing will be printed else we print the original line.

0 comments:

Sorting a file with related lines

Wednesday, April 17, 2013 , , 0 Comments

I have a file in which first row contains the number and second row contains a statement associated with it and so on like the below example:
12
stat1 
18
stat2
15
stat3
I need to print the output like sorting in descending order of numbers along with the statement related to it. So that the output should look like:
Time = 18
Stat = stat2
Time = 15
Stat = stat3
Time = 12
Stat = stat1
Below is the perl command that I have written which does the needed thing.
perl -lne 'if(/^\d+/){$k=$_}
           else{$x{$k}=$_}
           END{ 
               for(sort {$b<=>$a} keys %x){ 
               print "time=$_\nStat=$x{$_}";}
           }' file
time=18
Stat=stat2
time=15
Stat=stat3
time=12
Stat=stat1
Note:Precondition is time will come first and then the statement associated with it. 
Below is the explanation.

1. So store in a variable $k if the line start with a decimal point number.
2. Else case it is nothing but the statement. So store this line as a value to the previous stored $k.
   After parsing complete file.sort the keys of the hash in descending order by
3. sort  $b<=>$a and then print each and ever key and value in needed format.
Also please note:
1. sort $a<=>$b will sort the numbers in ascending order.
2. sort $b<=>$a will sort the numbers in descending order

0 comments:

Column wise comaprision using awk

Friday, March 29, 2013 , , , 2 Comments

There was a requirement once where i need to compare two files not with thier rows instead  i needed to do the comparision with columns.
I wanted only those rows where any of the columns in the lines differ.

for eg:
File1
1 A B C D
2 E F G H
File2
1 A Z C D
2 E F Y H
3 M N O P
Below is the Output I need:
file1 1 col2 B
file2 1 col2 Z
file1 2 col3 G
file2 2 col3 Y

Below is the solution in awk that i have written.
awk 'FNR==NR{a[FNR]=$0;next} {
if(a[FNR])
{split(a[FNR],b);
for(i=1;i<=NF;i++)
{
if($i!=b[i])
{
printf "file1 "b[1]" col"b[i-1]" "b[i]"\n";
printf "file2 "$1" col"b[i-1]" "$i"\n";
}
}
}
}'
Below is the test i made on my solaris server:


> nawk 'FNR==NR{a[FNR]=$0;next}{if(a[FNR]){split(a[FNR],b);for(i=1;i<=NF;i++){if($i!=b[i]){printf "file1 "b[1]" col"i-1" "b[i]"\n";printf "file2 "$1" col"i-1" "$i"\n";}}}}' file1 file2
file1 1 col2 B
file2 1 col2 Z
file1 2 col3 G
file2 2 col3 Y
>

2 comments:

Counting duplicates in a file

Tuesday, March 26, 2013 0 Comments

I have a file where column one has a list of family identifiers
AB
AB
AB
AB
SAR
SAR
EAR
Is there a way that I can create a new column where each repeat is numbered creating a new label for each repeat i.e.
AB_1
AB_2
AB_3
AB_4
SAR_1
SAR_2
EAR_1
Below is a pretty simple solution for this:
awk '{print $1"_"++a[$1]}' file
Since the hash map a has all the counters for all the duplicates. You can use that in the END block if you wish to see just the counters.

0 comments:

Converting single column to multiple columns

Tuesday, March 26, 2013 , 0 Comments

I have a file which contains all the entries in a single column like:
0
SYSCATSPACE
16384
13432
2948
1
1
TEMPSPACE1
1
1
applicable
1
2
USERSPACE1
4096
1888
2176
1
If I want to convert this in a tabular form of 3*6:
0 SYSCATSPACE 16384 13432 2948       1
1 TEMPSPACE1  1     1     applicable 1
2 USERSPACE1  4096  1888  2176       1
Below is the command that I will use:
perl -lne '$a.="$_ ";
           if($.%6==0){push(@x,$a);$a=""}
           END{for(@x){print $_}}' your_file
output would be :
> perl -lne '$a.="$_ ";if($.%6==0){push(@x,$a);$a=""}END{for(@x){print $_}}' temp
0 SYSCATSPACE 16384 13432 2948 1 
1 TEMPSPACE1 1 1 applicable 1 
2 USERSPACE1 4096 1888 2176 1

0 comments:

Capture all the letters which are repeated more than once

Tuesday, March 12, 2013 , 0 Comments

Recently i came across a need where i need to fetch all the letters in a line which are repeated more than once in a line contiguously.

for example :

lets say there a word "foo bar". I want the letter 'o' in this.
lets say there a word "foo baaar". I want the letters 'o','a' in this.
lets say there a word "foo baaar foo". I want the letters 'o','a' in this again.

Below is code which worked for me:

perl -lne 'push @a,/(\w)\1+/g;END{print @a}' your_file

The above command will scan complete file and prints just the letters that are repeated continguously in the file.

0 comments:

Summing up column values based upon ranges in another file

Friday, February 22, 2013 , 2 Comments

File 1 has ranges 3-9, 2-6 etc
    3 9
    2 6
    12 20

File2 has values: column 1 indicates the range and column 2 has values.
    1 4
    2 4
    3 5
    4 4
    5 4
    6 1
    7 1
    8 1
    9 4

I would like to calculate the sum of values (file2, column2) for ranges in file1). Eg: If range is 3-9, then sum of values will be 5+4+4+1+1+1+4 = 20

Below is the script for doing the same:

use strict;
use warnings;
use feature qw( say );

use List::Util qw( sum );
my $file1 = 'file1.txt';
my $file2 = 'file2.txt';

my @file2;
{   
   open(my $fh, '<', $file2)
      or die "Can't open $file2: $!\n";
   while (<$fh>) {
      my ($k, $v) = split;
      $file2[$k] = $v;
   }
}

{   
   open(my $fh, '<', $file1)
      or die "Can't open $file1: $!\n";
   while (<$fh>) {
      my ($start, $end) = split;
      say sum grep defined, @file2[$start .. $end];
   }
}

2 comments:

Capitalize every first letter of a word and others to lower case

Monday, February 18, 2013 0 Comments

How can you capitalize(Only first character) each word in a line using perl and change remaining to lower case?

let say there is a file:
> cat temp
hI thIs is woRld
How can we make it
Hi This Is World
Its very simple to do it in perl:
perl -pe 's/(\w+)/\u\L$1/g' your_file
If you want to do it inplace just add a -i flag:
perl -pi -e 's/(\w+)/\u\L$1/g' your_file

0 comments:

Print the next power of 2 for a given number

Wednesday, February 13, 2013 , 0 Comments

Below is the program that I have written for printing the next power of 2 for a given number.
The code mostly uses the bitwise operations in c/c++.
int main ()
{
int num;
scanf("%d",&num);
int count=0;
        if(!((num != 1) && (num&(num-1))))
        {
        printf("%d is already a power of two.\n",num);
        printf("%d is next number power of 2.\n",num*2);
        }
        else
        {
        while((num>>=1)&&(++count));
        printf("%0.0f",pow(2.0,count+1));
        }
}

0 comments:

Sorting files based upon the numeric value before the first field separator

Thursday, February 07, 2013 , 0 Comments

Lets say i have a list of files.

for eg:

ABCD5_Avgsdfgsg.txt
ABCD7_ff.txt
CD8_PKG_CV.txt
ABCD1_11.txt
BCD2_fbefjf.txt
D3_C.txt
ABCD4_123.txt
ABCD10_123.txt


I want to sort these files according to the first number before the first underscore.
I tried with sort but with no proper solution then i tried it in perl and this worked.Hopefully the below helps.

ls -1 | perl -F"_" -lane '$F[0]=~s/[a-zA-Z]//g;$X{$F[0]}=$_;END{foreach(sort {$a<=>$b} keys(%X)){print $X{$_}}}'

tested below:

> ls -1
ABCD10_123.txt
ABCD1_11.txt
ABCD4_123.txt
ABCD5_Avgsdfgsg.txt
ABCD7_ff.txt
BCD2_fbefjf.txt
CD8_PKG_CV.txt
D3_C.txt



> ls -1 | perl -F"_" -lane '$F[0]=~s/[a-zA-Z]//g;$X{$F[0]}=$_;END{foreach(sort {$a<=>$b} keys(%X)){print $X{$_}}}'
ABCD1_11.txt
BCD2_fbefjf.txt
D3_C.txt
ABCD4_123.txt
ABCD5_Avgsdfgsg.txt
ABCD7_ff.txt
CD8_PKG_CV.txt
ABCD10_123.txt
>

0 comments:

Creating a child process in perl

Thursday, January 31, 2013 , , 0 Comments

This example fork 10 child processes.
It will wait for all child's to finish before exiting.


#!/usr/local/bin/perl

use strict;
use warnings;

print "Starting main program\n";
my @childs;

for ( my $count = 1; $count <= 10; $count++) {
        my $pid = fork();
        if ($pid) {
        # parent
        #print "pid is $pid, parent $$\n";
        push(@childs, $pid);
        } elsif ($pid == 0) {
                # child
                sub1($count);
                exit 0;
        } else {
                die "couldnt fork: $!\n";
        }
}
foreach (@childs) {
        my $tmp = waitpid($_, 0);
         print "done with pid $tmp\n";

}
print "End of main program\n";

sub sub1 {
        my $num = shift;
        print "started child process for  $num\n";
        sleep $num;
        print "done with child process for $num\n";
        return $num;
}


Output looks like:

Starting main program
started child process for  1
started child process for  2
started child process for  3
started child process for  4
started child process for  5
started child process for  6
started child process for  9
started child process for  10
started child process for  7
started child process for  8
done with child process for 1
done with pid 5584
done with child process for 2
done with pid 5585
done with child process for 3
done with pid 5586
done with child process for 4
done with pid 5587
done with child process for 5
done with pid 5588
done with child process for 6
done with pid 5589
done with child process for 7
done with pid 5590
done with child process for 8
done with pid 5591
done with child process for 9
done with pid 5593
done with child process for 10
done with pid 5594
End of main program

0 comments:

Explicit in c++

Thursday, January 31, 2013 , 1 Comments

Many a times we wonder why this explicit keyword is used when ever we came across any c++ code. Here I would like to give a simple explanation of this keyword which can be more convincing to all.
Suppose you have a class String
class String {
public: 
String (int n);//allocate n bytes to the String object 
String(const char *p); // initializes object with char *p 
}
Now if you try
String mystring='x';
The char 'x' will be converted to int and will call String(int) constructor. But this is not what the user might have intended. So to prevent such conditions, we can define the class's constructor as explicit.
class String {
public: 
explicit String (int n); //allocate n bytes
String(const char *p); // initialize sobject with string p 
}

1 comments:

Creating a hash in perl with all the regex matches

Thursday, January 31, 2013 , 0 Comments

As i explained here :http://theunixshell.blogspot.com/2013/01/capturing-all-regex-matches-into-array.html about storing each and each regex match in an array,Now let's see how do we store each and every regex match in a hash instead.

Lets say we have text file like below:

hello world 10 20
world 10 10 10 10 hello 20
hello 30 20 10 world 10


I want to store each and every decimal integer here in a hash as a key and count of their occurances in a value for that key.

Below is the solution for that:

perl -lne '$a{$_}++for(/(\d+)/g);END{for(keys %a){print "$_.$a{$_}"}}' Your_file

output generated will be:

> perl -lne '$a{$_}++for(/(\d+)/g);END{for(keys %a){print "$_.$a{$_}"}}' temp
30.1
10.7
20.3






0 comments:

Delete empty lines in a file

Tuesday, January 29, 2013 , , 1 Comments

Some times there are some empty lines which we feel are redundant in the file and want to remove them.Below is the command in unix to do that.
sed -i '/^$/d' your_file
But there is also another way to do this:
grep . your_file > dest_file
In perl also we can acheive this as below:
perl -pi -e 's/^$//g' your_file
the above mentioned perl and sed solutions will do an inplace replacement in the file
If in case the lines have some spaces then:
perl -pi -e 's/^\s*$//g' your_file

1 comments:

Creating files using Awk

Thursday, January 24, 2013 , 0 Comments

I have 40,000 data files. Each file contains 1445 lines in single column. Now I need to rearrange the data in different order. The first number from each data file need to be collected and dumped in a new file (lets say abc1.dat). This particular file (abc1.dat) will contain 40,000 numbers.
And the second number from each data file need to be extracted and dumped in a another new file (let's say abc2.dat). This new file also will be containing 40,000 numbers. But only second numbers from each data file. At the end of this operation I should have 1445 files (abc1.dat, abc2.dat,...abc40000.dat) and each contains 40,000 data.

Below is a simple way to do it in awk:
awk '{print $1>"abc"FNR".txt"}' file*
file* above should refer to all 40k files.
Some flavors of unix does not support the above syntax,in such case go for:
awk '{x="abc"FNR".txt";print $1>x}' file*

0 comments:

List of columns in a table from SYBASE

Monday, January 21, 2013 , 0 Comments

I recently came across a need to create a file which has the columns of a table in sybase.Then I thought it would be better that we write a script which will fetch the column details by taking table name as an argument and store the output in a text file.Below is a simple perl script to do it.

As you can see help text is also there.So i guess i don't need to explain it.

#!/usr/bin/perl
######################################
#This is the script to list all the
#columns in the table.table names
#should be given as arguments to the
#script.
#example:
#script_name table_name_1 table_name_2 ...so on
######################################

use strict;
use warnings;
my $result;
unlink("output.txt");
foreach(@ARGV)
{
$result = qx{isql -U<user_name> -P<password> -D<dbname> <<EOF
set nocount on
SELECT sc.name FROM syscolumns sc INNER JOIN sysobjects so ON sc.id = so.id WHERE so.name = '$_'
go
exit
EOF
};
my @lines = split /\s+\n/, $result;
splice @lines,0,2;
$_=~s/ //g foreach @lines;

my $outfile  = "output.txt";
open (OUTFILE, ">>$outfile") || die "ERROR: opening $outfile\n";
print OUTFILE "$_\n------------\n".join "\n",@lines;
print OUTFILE "\n\n";
}
close OUTFILE;
################################################################################ 

0 comments:

Executing shell command in c/c++ and parsing the output

Thursday, January 17, 2013 , , , 0 Comments

Often we need to execute some shell command and get the output of that shell command in c.
system will simply execute the shell command but ther is no way using it for fetching its output.
below is the way where we can execute the command and also get its output into a c/c++ buffer.
FILE* pipe = popen("your shell command here", "r");
if (pipe)
{
char buffer[128];
while(!feof(pipe))
{
if(fgets(buffer, 128, pipe) != NULL){}
}
pclose(pipe);
buffer[strlen(buffer)-1] = '\0';
}

0 comments:

Search a string in multiple files recursively

Thursday, January 17, 2013 , , 2 Comments

Almost every unix programmer will need this at least once in a day.
For searching a string abc in all the files in the current direcory we use:
grep 'abc' *

If you want to serach in files which are under any sub directories also including the files in the current directory then we have to combine both find and grep:

find . -type f|xargs grep 'abc'

Another possible way is using exec of find command:
find . -type f -exec grep 'abc' {} \;

2 comments:

Capturing all the regex matches into an array in perl

Wednesday, January 16, 2013 , , 0 Comments

Often we need to track the list of matches whenever we use a regex.
for example lets say i have a file which looks like below:

Jan 1 1982
Dec 20 1983
jan 6 1984

Now if i want to store all the decimal number in the file in a array..How?

first thing is we need to use a regex match and store all the numbers into an array.

Below is the code for it :

perl -lne 'push @a,/\d+/g;END{print "@a"}' your_file

The above will output:

> perl -lne 'push @a,/\d+/g;END{print "@a"}' your_file
1 1982 20 1983 6 1984


In the same way you can use any other pattern in the match regex and capture those patterns in an array.

0 comments:

Perl's equivalent of "grep -f"

Thursday, January 10, 2013 , , 0 Comments

Lets say there are two files:

> cat file1
693661
11002
10995
48981
79600
> cat file2
10993   item    0
11002   item    6
10995   item    7
79600   item    7
439481  item    5
272557  item    7
224325  item    7
84156   item    6
572546  item    7
693661  item    7

using
grep -f file1 file2
we can filter the data in file2 but comparing the matching rows only with teh first column.

I have written a perl equivalent to this but yet not in a complete way.
the below command will simply compare the first field of the file 1 and present the output if it matches with the first field of file2.

> perl -F -lane 'BEGIN{$c=1}if($c==1){$x{$_}++};if(eof && $c==1){$c++;next};if($c==2){if($x{$F[0]}){print }}' file1 file2
11002   item    6
10995   item    7
79600   item    7
693661  item    7

0 comments:

Difference between Java and c++

Thursday, January 10, 2013 , 0 Comments

  1. C++ supports pointers whereas Java does not support pointers. But when many programmers questioned how you can work without pointers, the promoters began saying "Restricted pointers.” So we can say java supports Restricted pointers.
  2. At compilation time Java Source code converts into byte code .The interpreter execute this byte code at run time and gives output .Java is interpreted for the most part and hence platform independent. C++ run and compile using compiler which converts source code into machine level languages so c++ is plate from dependents
  3. Java is platform independent language but c++ is depends upon operating system machine etc. C++ source can be platform independent (and can work on a lot more, especially embedeed, platforms), although the generated objects are generally platofrom dependent but there is clang for llvm which doesn't have this restriction.
  4. Java uses compiler and interpreter both and in c++ their is only compiler
  5. C++ supports operator overloading multiple inheritance but java does not.
  6. C++ is more nearer to hardware then Java
  7. Everything (except fundamental types) is an object in Java (Single root hierarchy as everything gets derived from java.lang.Object).
  8. Java does is a similar to C++ but not have all the complicated aspects of C++ (ex: Pointers, templates, unions, operator overloading, structures etc..) Java does not support conditional compile (#ifdef/#ifndef type).
  9. Thread support is built-in Java but not in C++. C++11, the most recent iteration of the C++ programming language does have Thread support though.
  10. Internet support is built-in Java but not in C++. However c++ has support for socket programming which can be used.
  11. Java does not support header file, include library files just like C++ .Java use import to include different Classes and methods.
  12. Java does not support default arguments like C++.
  13. There is no scope resolution operator :: in Java. It has . using which we can qualify classes with the namespace they came from.
  14. There is no goto statement in Java.
  15. Exception and Auto Garbage Collector handling in Java is different because there are no destructors into Java.
  16. Java has method overloading, but no operator overloading just like c++.
  17. The String class does use the + and += operators to concatenate strings and String expressions use automatic type conversion,
  18. Java is pass-by-value.
  19. Java does not support unsigned integer.

0 comments:

Bulk rename of files in unix

Wednesday, January 09, 2013 , , , 0 Comments

Most of the time it is required that w eneed to rename the files in bulk.
this can be done in many ways,Mostly people do it by  writing a simple shell script.

I found a better way to do it using just the command line in a single command.
Let's say we have some files as shown below.Now i want remove the part -(ab...) from those files.
> ls -1 foo*
foo-bar-(ab-4529111094).txt
foo-bar-foo-bar-(ab-189534).txt
foo-bar-foo-bar-bar-(ab-24937932201).txt
So the expected file names would be :
> ls -1 foo*
foo-bar-foo-bar-bar.txt
foo-bar-foo-bar.txt
foo-bar.txt
Below is a simple way to do it.
> ls -1 | nawk '/foo-bar-/{old=$0;gsub(/-\(.*\)/,"",$0);system("mv \""old"\" "$0)}'
Explanation:

ls -1
Will list all the files in a single column in a directory

nawk '/foo-bar-/ 
The processing is done only for a file names with has foo-bar- as a part of their names.

old=$0 
  initially storing the file name in a variable.
gsub(/-\(.*\)/,"",$0) 
 Removing the undesired part of the file name.

mv \""old"\" "$0 
This will be expanded to :mv "foo-bar-(ab-4529111094).txt" foo-bar-foo-bar-bar.txt.You might ask why a '"'.because there is possibility that the fine name might consist a space or any other special character(in our case it has '(' ).

system("mv \""old"\" "$0) 
This will execute on teh command line what ever is there inside the system call.

Note: nawk is specific for solaris unix.for other falvours of unix just awk is enough.

0 comments:

Shebang line in shell script

Tuesday, January 08, 2013 0 Comments

I have simple perl script as below:

#!/usr/bin/perl

use strict;
use warnings;

print "hello ! world\n";

I can execute this script as below:
>temp.pl
hello ! world
>

if i add some comments like this:
 
#this script is just for test
#the shebang
#!/usr/bin/perl
use strict;
use warnings;
print "hello ! world\n";
 
and when i try to execute,it gives me output as below:

> temp.pl
use: Command not found.
use: Command not found.
print: Command not found.
> 
 
The point here is shebang line should be always at the top no matter what. but can anybody explain me why?

What wiki says?

In computing, a shebang (also called a sha-bang,hashbang,pound-bang,hash-exclam,or hash-pling) is the character sequence consisting of the characters number sign and exclamation mark (that is, "#!") when it occurs as the initial two characters on the initial line of a script.

Under Unix-like operating systems, when a script with a shebang is run as a program, the program loader parses the rest of the script's initial line as an interpreter directive; the specified interpreter program is run instead, passing to it as an argument the path that was initially used when attempting to run the script.[8] For example, if a script is named with the path "path/to/script", and it starts with the following line:

Why should it always be the first line?

The shebang must be the first line because it is interpreted by the kernel, which looks at the two bytes at the start of an executable file. If these are #! the rest of the line is interpreted as the executable to run and with the script file available to that program on stdin. (Details vary slightly, but that is the picture).

Since the kernel will only look at the first two characters and has no notion of further lines, you must place the hash bang in line 1.

Now what happens if the kernel can't execute a file beginning with #whatever? The shell, attempting to fork an executable and being informed by the kernel that it can't execute the program, as a last resort attempts to interpret the file contents as a shell script. Since the shell is not perl, you get a bunch of errors, exactly the same as if you attempted to run

0 comments:

Indentation in vi editor

Monday, January 07, 2013 , 1 Comments

In general many of us might get irritated by working on vi editor since we are more used to MSword/any windows editor.Below i present some very useful tips for indentation purposes in vi editor.

In the commands below, "re-indent" means "indent lines according to your indentation settings." shiftwidth is the primary variable that controls indentation.

General Commands
>>   Indent line by shiftwidth spaces
<<   De-indent line by shiftwidth spaces
5>>  Indent 5 lines
5==  Re-indent 5 lines

>%   Increase indent of a braced or bracketed block (place cursor on brace first)
=%   Reindent a braced or bracketed block (cursor on brace)
<%   Decrease indent of a braced or bracketed block (cursor on brace)
]p   Paste text, aligning indentation with surroundings

=i{  Re-indent the 'inner block', i.e. the contents of the block
=a{  Re-indent 'a block', i.e. block and containing braces
=2a{ Re-indent '2 blocks', i.e. this block and containing block

>i{  Increase inner block indent
<i{  Decrease inner block indent

You can replace { with } or B, e.g. =iB is a valid block indent command. Take a look at "Indent a Code Block" for a nice example to try these commands out on.

Also, remember that
.    Repeat last command
, so indentation commands can be easily and conveniently repeated.

Re-indenting complete files
Another common situation is requiring indentation to be fixed throughout a source file:
gg=G  Re-indent entire buffer
You can extend this idea to multiple files:
" Re-indent all your c source code:
:args *.c
:argdo normal gg=G
:wall
Or multiple buffers:
" Re-indent all open buffers:
:bufdo normal gg=G:wall

In Visual Mode
Vjj> Visually mark and then indent 3 lines

In insert mode
These commands apply to the current line:
CTRL-T   insert indent at start of line
CTRL-D   remove indent at start of line
0 CTRL-D remove all indentation from line

Ex commands
These are useful when you want to indent a specific range of lines, without moving your cursor.
:< and :> Given a range, apply indentation e.g.
:4,8>   indent lines 4 to 8, inclusive

Indenting using markers
Another approach is via markers:
ma     Mark top of block to indent as marker 'a'
...move cursor to end location
>'a    Indent from marker 'a' to current location

Variables that govern indentation
You can set these in your .vimrc file.
set expandtab       "Use softtabstop spaces instead of tab characters for indentation
set shiftwidth=4    "Indent by 4 spaces when using >>, <<, == etc.
set softtabstop=4   "Indent by 4 spaces when pressing <TAB>

set autoindent      "Keep indentation from previous line
set smartindent     "Automatically inserts indentation in some cases
set cindent         "Like smartindent, but stricter and more customisable
Vim has intelligent indentation based on filetype. Try adding this to your .vimrc:
if has ("autocmd")
    " File type detection. Indent based on filetype. Recommended.
    filetype plugin indent on
endif

1 comments: