file-monitor is a simple Perl script to monitor a directory path for new files, updated files and deleted files.
It can be set to look for new files in a given interval of seconds (e.g.: -n 30)
and also can be set to check for updated and deleted files in another interval of seconds (e.g.: -c 12)
Download: http://trizen.googlecode.com/files/file-monitor
Trizen's Perl blog
You can find on this blog many useful Perl scripts, maybe some hidden features of Perl and some proof of concept code...
Tuesday, April 10, 2012
Saturday, March 24, 2012
Expand string
It's been a while since my last post...
Today I've had a tricky problem while rewriting 'trizen' program (Trizen's AUR Package Manager), which, first time I thought it's really hard to solve, but turned out to be so easy, elegant and fast that I'd want to share it with you guys :)
Problem:
I have a string like this:$string = 'perl-{file-{which,basedir,copy-recursive},pathtools,path-class},mplayer';
Now, I need to expand it into:
@a=(
'perl-file-which',
'perl-file-basedir',
'perl-file-copy-recursive',
'perl-pathtools',
'perl-path-class',
'mplayer',
);
Solution
Short solution: $string = `echo $string`;
Long solution: http://trizen.googlecode.com/files/expand_to_absolute_values.pl
I hope you find it amusing :)
Tuesday, March 13, 2012
Regex: Universal HTML href URL collector
Did you ever wondered if there exists a universal regular expression to collect all URLs from a HTML source file?
There are some:
# An optimized version:
while ($html =~ /\bhref\s*=\s*(?(?=")"(.*?)"|(?(?=')'(.*?)'|([^>\s]+)))/gsi){
print "Found: <$+>\n";
}
# An optimized version:
while ($html =~ /\bhref\s*=\s*(?(?=")"(.*?)"|(?(?=')'(.*?)'|([^>\s]+)))/gsi){
print "Found: <$+>\n";
}
# Or another way of doing it (requires perl>=5.010):
while ($html =~ /\bhref\s*=\s*(?<quote>['"])?(?(<quote>)(.*?)\g{quote}|([^>\s]+))/gsi) {
print "Found: <$+>\n";
}
# Or a smaller, but slower version:
while($html =~ /\bhref\s*=\s*(['"]?)(.*?)(??{$1 || qr{[>\s]} })/gsi){
print "Found: <$+>\n";
}
while ($html =~ /\bhref\s*=\s*(?<quote>['"])?(?(<quote>)(.*?)\g{quote}|([^>\s]+))/gsi) {
print "Found: <$+>\n";
}
# Or a smaller, but slower version:
while($html =~ /\bhref\s*=\s*(['"]?)(.*?)(??{$1 || qr{[>\s]} })/gsi){
print "Found: <$+>\n";
}
Enjoy it! :)
Wednesday, March 7, 2012
GD::Simple
GD::Simple is a simple interface to GD library which is an open source code library for the dynamic creation of images by programmers.
I've had a lot of fun with this module. See my testing script: here (a lot of mess)
Friday, March 2, 2012
GTK Youtube Viewer
GTK Youtube Viewer is a personal project started in 12 September 2010 as my first Gtk2/Glade project.
It's a simple application to search for Youtube videos and streaming them with MPlayer.
For a while, after the release of 0.6.0 version, the project was abandoned, but starting with 2012, I've released version 2.0.0 (result of two weeks of hard work). It was almost rewritten from scratch and redesigned.
As you can see in the screenshots, it supports many options for search, it displays thumbnails, title, description and some extra details.

More details: http://code.google.com/p/trizen/
AUR Link: https://aur.archlinux.org/packages.php?ID=40750
Github: https://github.com/trizen/gtk-youtube-viewer
Softpedia: http://linux.softpedia.com/get/Multimedia/Video/Youtube-Viewer-60648.shtml
Download: http://trizen.googlecode.com/files/gtk-youtube-viewer.tar.gz
It's a simple application to search for Youtube videos and streaming them with MPlayer.
For a while, after the release of 0.6.0 version, the project was abandoned, but starting with 2012, I've released version 2.0.0 (result of two weeks of hard work). It was almost rewritten from scratch and redesigned.
The current version is 2.0.4

More details: http://code.google.com/p/trizen/
AUR Link: https://aur.archlinux.org/packages.php?ID=40750
Github: https://github.com/trizen/gtk-youtube-viewer
Softpedia: http://linux.softpedia.com/get/Multimedia/Video/Youtube-Viewer-60648.shtml
Download: http://trizen.googlecode.com/files/gtk-youtube-viewer.tar.gz
Tuesday, February 21, 2012
Perl optimization
Perl is fast, but this is up to the programmer.
There is more than one way to do it, and some ways are faster than others.
Things that can slow down your program:
When regular expressions are needed:
tr///:
tr/h/h/s;
The above codes replaces two or more consecutive 'h' letters with one 'h'.
s///: (notice the '+' sign, it's very important for efficiency)
s/[0-9a-f]+//gi;
tr///:
tr/0-9a-fA-F//d;
The above codes deletes from a string any hex characters.
There is more than one way to do it, and some ways are faster than others.
Things that can slow down your program:
- Regular expressions (m// and s///)
- External modules
- sub recursions
- Loading files inside memory when is not needed
- Reading external data (WWW, HDD, USB)
How to improve your programs?
Use regular expressions when they are really needed, but not for simple things that can be done in a faster way.
The following statements are the same:
The following statements are the same:
Index (faster):
if (index($str, 'word') > -1) {
print 'found';
}
Regex (slower):
if ($str =~ /word/) {
print 'found';
}
--------------
tr/// (faster)
my $str = 'U)n@~r)@=/,.3-?{]a[|})d\\a~b|^l~"e';
$str =~ tr/A-Za-z0-9_//dc;
s/// (slower)
my $str = 'U)n@~r)@=/,.3-?{]a[|})d\\a~b|^l~"e';
$str =~ s/\W+//g;
tr/// (faster)
my $str = 'U)n@~r)@=/,.3-?{]a[|})d\\a~b|^l~"e';
$str =~ tr/A-Za-z0-9_//dc;
s/// (slower)
my $str = 'U)n@~r)@=/,.3-?{]a[|})d\\a~b|^l~"e';
$str =~ s/\W+//g;
When speed is really necessary (for example if do you want to create a pipe menu for some window manager, then you need every bit of speed in order to generate the menu fast as possible after the user right-clicked on desktop (see: obmenu-generator)
Some users (me) may even capture variable lengths of text using index + substr just like you may use: $str =~ /^Name=(.+)/m
Example:
my $str = <<'TEXT';
Encoding=UTF-8
GenericName=gFTP
Exec=gftp %u
Terminal=false
Name=gFTP
X-MultipleArgs=false
Type=Application
Icon=gftp.png
Categories=Application;Network;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gftp
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=2.0.19
TEXT
my $i = index($str, "\nName=");
print substr($str, $i + 6, index($str, "\n", $i + 6) - $i - 6);
It prints "gFTP" (without a new line), and is faster than using a regular expressions with capture.
substr + (r)index make a very good team.
Q: How to get the base name from a full path name?
A: Use substr + rindex :)
Of course, it may be intuitive to use a regex, something like:
my ($name) = $path =~ m{^.*/(.+)}
which is fine when is used on a real path (that are generally small), but when is used against a really large data, a lot of backtracking occurs which really slows down your program, so I suggest to use:
my $name = substr($path, rindex($path, '/')+1);
Q: How to mask some numbers inside a string?
A: Use substr + length
Consider this example: masking numbers. ('4512872356698' to '451287XXX6698')
A substitution with eval (/e) should work, but is slower than a substr + length.
Here are my answers: http://perlmonks.org/?node_id=953985
More tips:
- Avoid substitution with eval (/e) - in fact try to avoid eval at all
- Use substr + (r)index whenever is needed.
- Use hashes instead to iterate over an array.
- Use tr/// when is applicable instead of s///
- Use small and fast code inside loops
- Do not make unneeded copies of data (be direct)
- Use configuration files written in Perl instead of parsing plain text files*
* For configuration files, instead of using something like this:
key1 = value
key2 = value
use something like this:
our $CONFIG = {
key1 => 'value',
key2 => 'value',
}
and load the configuration with do $config_file and then access the values with $CONFIG->{key1} or $CONFIG->{key2};
When regular expressions are needed:
- Write optimized regular expressions
- Use anchors (^ $ \A \z \Z)
- Avoid matching at the end of a line or string
- Write some plain text inside regular expressions to help the optimizer to find the position where to start the match
- Read Mastering Regular Expressions Book
There are some common mistakes, that I used to make in the past.
For example, if do you want to replace more spaces with one, you can use: s/ +/ /g, but if you apply this on a long string which contains a lot of spaces, but not two or more spaces together, it makes the substitution anyway. It replaces one space with one space. Is this efficient? Of course not. We may use: s/ +/ /g (notice the two spaces and a plus), this allow the optimizer to find in the string the position where two spaces are present, and one space replaced by one space is avoided and the efficiency has been increased. Anyway, you may consider the following code to be more helpful: join(' ', split(' ', $str)). It replaces any white-space characters with a single space, removes the leading and trailing white-spaces and is very fast!
Use tr/// instead of s///
If do you want to delete some characters or to replace one character with another, use tr///.
The following statements are the same, but tr/// is faster!
s///:
s/hh+/h/g;
Use tr/// instead of s///
If do you want to delete some characters or to replace one character with another, use tr///.
The following statements are the same, but tr/// is faster!
s///:
s/hh+/h/g;
tr///:
tr/h/h/s;
The above codes replaces two or more consecutive 'h' letters with one 'h'.
s///: (notice the '+' sign, it's very important for efficiency)
s/[0-9a-f]+//gi;
tr///:
tr/0-9a-fA-F//d;
The above codes deletes from a string any hex characters.
find-fast
A simple Perl script to list files from directories and it's sub-directories (infinite levels).
It's almost the same as File::Find, but with another algorithm. As you can see, I do not use chdir in the code, just a deep recursion to find_fast (ahidden awesome feature of Perl).
Also see: perl-magic-trick
It's almost the same as File::Find, but with another algorithm. As you can see, I do not use chdir in the code, just a deep recursion to find_fast (a
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
sub find_fast {
foreach my $path (@_) {
my @dirs;
opendir(my $dir_h, $path) or next;
while (defined(my $file = readdir $dir_h)) {
next if $file ~~ ['.', '..'];
push @dirs, "$path/$file" if -d "$path/$file";
print "$path/$file\n";
}
closedir $dir_h;
find_fast(@dirs) if @dirs;
}
}
find_fast(@ARGV);
Also see: perl-magic-trick
obmenu-generator
Openbox Menu Generator is a simple Perl script that generates a valid Openbox XML (static or pipe) menu.
It is related to: fbmenugen and menutray.
It can generate a simple menu, without icons, or a iconified one, using GDBM_File to store a hash of ICON_NAME => ICON_PATH for a better performance.
The database updates itself every time when a new applications has been installed and the script is executed as obmenu-generator -i
For more details, see: obmenu-generator -h
AUR Link: https://aur.archlinux.org/packages.php?ID=47711
It is related to: fbmenugen and menutray.
It can generate a simple menu, without icons, or a iconified one, using GDBM_File to store a hash of ICON_NAME => ICON_PATH for a better performance.
The database updates itself every time when a new applications has been installed and the script is executed as obmenu-generator -i
For more details, see: obmenu-generator -h
fbmenugen
Fluxbox Menu Generator is a menu generator (related to menutray and obmenu-generator).
It generates a valid Fluxbox menu file with the applications found on /usr/share/applications ordered on categories. It also provides a configuration file that allows the user to customize the menu.
In the screenshot is version 0.6.2, but the current version is 0.7.1 which provides a new configuration files and a better (faster) support for icons (maybe, in v0.7.2 I will use an icon database for a better performance (just like I did in obmenu-generator).
AUR Link: https://aur.archlinux.org/packages.php?ID=39331
It generates a valid Fluxbox menu file with the applications found on /usr/share/applications ordered on categories. It also provides a configuration file that allows the user to customize the menu.
In the screenshot is version 0.6.2, but the current version is 0.7.1 which provides a new configuration files and a better (faster) support for icons (maybe, in v0.7.2 I will use an icon database for a better performance (just like I did in obmenu-generator).
AUR Link: https://aur.archlinux.org/packages.php?ID=39331
Subscribe to:
Posts (Atom)




