Thursday, June 25, 2009

Editing Very Very Large File

Suppose we want to do changes in few lines in a very very large file. It is not possible to open such a big file(say size in GBs > RAM+Swap size) in a editor. Even sed/awk takes very long time, because they do pattern matching if mentioned on every line, otherwise, we can do one line editing with a line number. I have written a Perl Script to edit multiple lines independently. It uses sed commands to edit a line.

Format of Config file is:
line_number:sed_command


#!/usr/bin/perl -w
#===============================================================================
#
# FILE: ed_large_file.pl
#
# USAGE: ./ed_large_file.pl <config_file> <file_name> [overwrite}
#
# DESCRIPTION: Edit very[ very] large file
#
# OPTIONS: ---
# REQUIREMENTS: ---
# BUGS: ---
# NOTES: ---
# AUTHOR: Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
# VERSION: 1.0
# CREATED: Thursday 25 June 2009 02:32:37 IST IST
# REVISION: ---
#===============================================================================

use strict;
use warnings;

if (@ARGV < 2)
{
print STDERR "$0: <config_file> <file_name> [overwrite]\n";
print STDERR "!!!Be careful while using [overwrite] option,\n";
print STDERR "because original file will be deleted.\n";
exit(-1);
}

my $conf_file = $ARGV[0];
my $large_file = $ARGV[1];
my $overwrite = 0;
if (@ARGV >= 3 && $ARGV[2] eq "overwrite")
{
$overwrite = 1;
}

my $temp_file = `dirname $large_file`;
chomp($temp_file);
if ($temp_file eq "" || (!(-d $temp_file)))
{
print STDERR "$0: Cannot find dirname for temporary file.\n";
print STDERR "Please check path of file '$large_file'\n";
exit(-1);
}

$temp_file = $temp_file . "/temp";
print "Temporary file is '$temp_file'\n";

## Read config file
print "Reading config file '$conf_file'\n";
open(CFH, "$conf_file") or die("Cannot read Config file '$conf_file'\n");
my $line;
my %lineno_sedcmd;
while ($line = <CFH>)
{
chomp($line);
my ($lineno, $sedcmd) = split /:/, $line, 2;
if (defined($sedcmd))
{
$lineno_sedcmd{$lineno} = $sedcmd;
print "$lineno $lineno_sedcmd{$lineno}\n";
# Verifying sedcmd before running it;
# it gives a chance to reedit config file
my $cmd = "echo \"Mitesh Singh Jat\" | sed '$sedcmd' 1> /dev/null 2>&1";
if (!(system($cmd) == 0))
{
print STDERR "$0: sed command '$sedcmd' for line '$lineno'";
print STDERR "is having error. Please recheck with \$ man sed\n";
close(CFH);
exit(-1);
}
}
}
close(CFH);

my @line_nos;
foreach (sort keys (%lineno_sedcmd))
{
push(@line_nos, $_);
}

## Open large file
open(LFH, "$large_file") or die("$0: Cannot open file '$large_file'");
## Temporary File
open(OFH, ">$temp_file") or die("$0: Cannot create temporary file '$temp_file'");
my $nline = 0;
my $i = 0;
my $end_idx = @line_nos - 1;
print "Processing...";
while ($line = <LFH>)
{
++$nline;
if ($line_nos[$i] == $nline) # now edit
{
++$i; # This config line is over
if ($i > $end_idx)
{
$i = $end_idx;
}
chomp($line);
my $cmd = "echo \"$line\" | sed '$lineno_sedcmd{$nline}'";
#print "$cmd\n";
my $out_line = `$cmd`;
print OFH "$out_line";
print " $nline"; #sleep 1; # to see progress :)
}
else
{
print OFH "$line";
}
}

print "\n";

close(OFH);
close(LFH);

if ($overwrite == 0)
{
print "done\n";
exit(0);
}

## Overwite original file by deleting it and moving temp
print "Overwriting...\n";
my $cmd = "rm -f $large_file \&\& mv $temp_file $large_file";
print "$cmd\n";
system($cmd) == 0
or die("Problem in overwriting. '$cmd' failed: $?\n");
print "done\n";
exit(0);


Sample Run:


--(0 : 618)> ./ed_large_file.pl
./ed_large_file.pl:
<config_file> <file_name> [overwrite]
!!!Be careful while using [overwrite] option,

because original file will be deleted.

--(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)--
--(255 : 619)> cat large_file.txt
Shree Ganeshay Namah
Shri Bharat Singh Jat
Smt Amita Jat
Mitesh Jat
Shikha Jat
Shilpa Jat
This is garbage line. Please delete it.
--(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)--
--(0 : 620)> cat large_file.conf
1:s/^.*$/!!&!!/
4:s/ / Singh /
7:/.*/d
--(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)--
--(0 : 621)> ./ed_large_file.pl large_file.conf large_file.txt
Temporary file is './temp'
Reading config file 'large_file.conf'
1 s/^.*$/!!&!!/
4 s/ / Singh /
7 /.*/d
Processing... 1 4 7
done
--(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)--
--(0 : 622)> cat ./temp
!!Shree Ganeshay Namah!!
Shri Bharat Singh Jat
Smt Amita Jat
Mitesh Singh Jat
Shikha Jat
Shilpa Jat
--(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)--
--(0 : 623)> ./ed_large_file.pl large_file.conf large_file.txt overwrite
Temporary file is './temp'
Reading config file 'large_file.conf'
1 s/^.*$/!!&!!/
4 s/ / Singh /
7 /.*/d
Processing... 1 4 7
Overwriting...
rm -f large_file.txt && mv ./temp large_file.txt
done
--(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)--
--(0 : 624)> cat large_file.txt
!!Shree Ganeshay Namah!!
Shri Bharat Singh Jat
Smt Amita Jat
Mitesh Singh Jat
Shikha Jat
Shilpa Jat
--(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)--
--(0 : 625)>

Tuesday, June 2, 2009

Web Access through Proxy Server by Terminal Applications

In many companies/Universities, the web access is granted through Proxy Server (Usually SQUID; hence port 3128).
There are many terminal applications (run on command line interface), which access Internet/Web. For example:
wget (to download file), ftp, lynx/links (to access website), apt/yum (to download and install package). If we are behind
proxy, these applications do not work. The easy solution is to set some shell environment variables, explained below:

For accessing web(lynx/links) using a non-authenticated proxy:
$ export http_proxy="http://proxy.yourcompany.com:3128"

Verify that the setting took place
$ echo $http_proxy
http://proxy.yourcompany.com:3128

For accessing web(lynx/links) using a authenticated proxy:
$ export http_proxy="http://username:password@proxy.yourcompany.com:3128"

If you want the change to be permanent (there each time you open a terminal),
add the export line to .bashrc in your 'home' directory.
$ echo 'export http_proxy="http://proxy.yourcompany.com:3128"'″ >> ~/.bashrc

Secure HTTP (over SSL) access
$ export https_proxy="https://proxy.yourcompany.com:3128"

FTP access
$ export ftp_proxy="ftp://proxy.yourcompany.com:3128"

Sunday, May 31, 2009

Making Soundcard Work in Macbook Pro

After installing Debian 5.0 (Lenny) on Macbook Pro (4,1), I found that
sound card was detected, but there was no sound. Then, I come to know
that, model=mbp3 option must be passed to snd-hda-intel kernel driver, to
make soundcard work. This is content of /etc/modprobe.d/sound file.


$ cat /etc/modprobe.d/sound

options snd slots=snd-hda-intel
# u1Nb.bVcdGDjFCiF:82801H (ICH8 Family) HD Audio Controller
alias snd-card-0 snd-hda-intel
# Add the following line as an option to snd_hda_intel module
options snd_hda_intel model=mbp3

Tuesday, May 26, 2009

Securing Your Root Using GRUB

Generally, we forget to provide password security for GRUB boot loader.

If we do not provide password, any one can get access to root login without giving

root password, just by editing “kernel” parameters to “single” or “1″.

Therefore, you can prevent this editing by providing password.

$ grub-md5-crypt
Password:
Retype password:
$1$BRvj2/$A0Xj.CeywUG/iL6j/15HC.

(you can provide any password, you want. But please remember this by heart)
and paste this output in /boot/grub/menu.lst below timeout
or default as


$vi /boot/grub/menu.lst
...
timeout 10
...
password --md5 $1$BRvj2/$A0Xj.CeywUG/iL6j/15HC
...

Now, reboot and try to modify the kernel parameters. You will not be
able to until you press p and provide the password.

Friday, May 22, 2009

Macbook Pro Touchpad: Synaptics Configuration in xorg.conf

I was trying to use touchpad on Macbook Pro (4,1) in Debian 5.0 (Lenny).
By default, it does not have tapping support, and multitouch support.
Even touchpad driver was also unavailable. Therefore, I had compiled
Linux kernel 2.6.29.3 added support for Apple Macbook Touchpad Driver.
Then after booting in new kernel with NVIDIA 8600 GT driver, I have
modified the xorg.conf with following lines.

## In case, you want to revert
$ sudo cp /etc/X11/xorg.conf /etc/X11/xorg.conf.bk
$ sudo vi /etc/X11/xorg.conf



...
Section "ServerLayout"
Identifier "Layout0"
...
# Add Synaptics Touchpad as mouse
InputDevice "Synaptics Touchpad" "SendCoreEvents" #"CorePointer"
InputDevice "Mouse0" "CorePointer"
EndSection

...

Section "Module"
...
# Load synaptics driver for Macbook Pro Touchpad
Load "synaptics"
EndSection

...

Section "InputDevice"
Identifier "Synaptics Touchpad"
Driver "synaptics"
Option "SendCoreEvents" "true"
Option "Device" "/dev/mouse0"
Option "Protocol" "auto-dev"
# not using edge scrolling
Option "HorizEdgeScroll" "0"
Option "VertEdgeScroll" "0"

# use two finger scrolling
Option "VertTwoFingerScroll" "1"
Option "HorizTwoFingerScroll" "1" # set to 0 if you don't want horizontal scrolling

# scroll speed, lower is faster
Option "HorizScrollDelta" "15"
Option "VertScrollDelta" "15"

# minimum pressure motion factor
Option "PressureMotionMinZ" "10"

# touch and untouch thresholds, higher numbers if you like to push hard
Option "FingerLow" "20"
Option "FingerHigh" "60" # change to 30 or 40 if you like

# FingerPress (Integer) : Above which counts as press
Option "FingerPress" "130"

# borders based on output from synclient
Option "LeftEdge" "70"
Option "RightEdge" "1120"
Option "TopEdge" "50"
Option "BottomEdge" "750"

# speeds, smaller number for a slower mouse
Option "MinSpeed" "0.8" # 0.5 is very slow, 1.5 is very fast
Option "MaxSpeed" "1.3" # up to 1.5 works ok
Option "AccelFactor" "0.10"

# tap times, change to suit your tapping habits
Option "MaxTapMove" "100"
Option "MaxTapTime" "100"
Option "MaxDoubleTapTime" "200"

# don't change these or two finger tap stops working
Option "TapButton2" "3"
Option "TapButton3" "2"

# must be commented out or normal tapping wont work
#Option "TapButton1" "0"

# Right Top Corner Button as right click
Option "RTCornerButton" "2"
Option "RBCornerButton" "0"

# Left Top Corner Button as middle click
Option "LTCornerButton" "3"
Option "LBCornerButton" "0"

# Palm Detection: Useful while typing
Option "PalmDetect" "on"
Option "PalmMinWidth" "10"
Option "PalmMinZ" "200"

# needed for disabled while typing fix
Option "SHMConfig" "on"
EndSection
...



Sunday, May 10, 2009

Pidgin: Buddy List Window Resize is not Working

I am regular user of Pidgin Multiprotocol Instant Messenger (IM)
for Yahoo! and Gtalk IMs.
The buddy list window was getting wider and wider after several
uses. I tried to resize the window. But I was not able to do so.
Then I think to change the configuration file to resize the window.
The configurations are stored in ~/.purple/prefs.xml

I then, opened this file and searched for 'width'
The width in which I was interested is related to 'buddy list window'
i.e. look for section 'blist' and change the width variable according
to your need (I had set it to 300).
<pref name='blist'>
...
...
<pref name='width' type='int' value='300'/>
...
...
</pref>

Save this file and restart pidgin and viola!!
This Works :)

Wednesday, April 8, 2009

Sending stderr (Standard Error) to Pipe

Many times we want to send output of standard error (stderr)
to pipe '|', so that we can use it as input for another command.

For example, while compilation of program, we are mostly interested
in error/warning messages. We can not get those lines by following
command:

$ make | egrep -i "error|warning"

so how can we can get only those error/warning message lines. We
just need to bind stderr (file handle 2) with stdout (file handle 1).
"2>&1"
The following example shows this:

$ make 2>&1 | egrep -i "error|warning"