<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>handyfloss &#187; Perl</title>
	<atom:link href="http://handyfloss.net/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://handyfloss.net</link>
	<description>Because FLOSS is handy, isn&#039;t it?</description>
	<lastBuildDate>Tue, 17 Jan 2012 09:04:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Making a PDF grayscale with ghostscript</title>
		<link>http://handyfloss.net/2008.09/making-a-pdf-grayscale-with-ghostscript/</link>
		<comments>http://handyfloss.net/2008.09/making-a-pdf-grayscale-with-ghostscript/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 16:56:09 +0000</pubDate>
		<dc:creator>isilanes</dc:creator>
				<category><![CDATA[howto]]></category>
		<category><![CDATA[en]]></category>
		<category><![CDATA[FLOSS]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[PS/PDF]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://handyfloss.net/?p=422</guid>
		<description><![CDATA[A request from a friend made me face the problem of converting a color PDF into a grayscale one. Searching the web provided some ways of doing so with Adobe Acrobat, via some obscure menu item somewhere. However, the very same operation could be undertaken with free tools, such as ghostscript. I found a way [...]]]></description>
			<content:encoded><![CDATA[<p>A request from a friend made me face the problem of converting a color <a href="http://en.wikipedia.org/wiki/Portable Document Format">PDF</a> into a <a href="http://en.wikipedia.org/wiki/grayscale">grayscale</a> one. Searching the web provided some ways of doing so with <a href="http://en.wikipedia.org/wiki/Adobe Acrobat">Adobe Acrobat</a>, via some obscure menu item somewhere.</p>
<p>However, the very same operation could be undertaken with free tools, such as <a href="http://en.wikipedia.org/wiki/ghostscript">ghostscript</a>. I found a way to do it in the <a href="http://vince-debian.blogspot.com/2008/05/pdf-conversion-to-grayscale.html">YANUB blog</a>, and I will copy-paste it here, with a small modification.</p>
<p>Assuming we have a file called color.pdf, and we want to convert it into grayscale.pdf, we could run the following command (all in a single line, and omitting the &#8220;\&#8221; line continuation marks):</p>
<div class="codeblock">
% gs -sOutputFile=grayscale.pdf -sDEVICE=pdfwrite \<br />
  -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \<br />
  -dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH color.pdf
</div>
<p>I prefer the above to YANUB&#8217;s version below (in red what he lacks, in blue what I lack), because a shell operation is substituted by some option(s) of the command we are running:</p>
<div class="codeblock">
% gs -sOutputFile=grayscale.pdf -sDEVICE=pdfwrite \<br />
  -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \<br />
  -dCompatibilityLevel=1.4 <span style="color:red">-dNOPAUSE -dBATCH</span> color.pdf <span style="color:blue">< /dev/null</span>
</div>
<p>A sample <a href="http://en.wikipedia.org/wiki/Perl">Perl</a> script to alleviate the tedious writing above:</p>
<div class="codeblock">
#!/usr/bin/perl -w<br />
use strict;<br />
my $infile = $ARGV[0];<br />
my $outfile = $infile;<br />
$outfile =~ s/\.pdf$/_gray.pdf/;<br />
system &#8220;gs -sOutputFile=$outfile -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray   -dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH $infile&#8221;
</div>
<p>Assuming we call the Perl script &#8220;togray.pl&#8221;, and that we have a color file &#8220;input.pdf&#8221;, we could just issue the command:</p>
<div class="codeblock">
% togray.pl input.pdf
</div>
<p>and we would get a grayscale version of it, named &#8220;input_gray.pdf&#8221;.</p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://handyfloss.net/2008.10/usable-compiz-fusion-zoom-to-window/" title="Usable Compiz Fusion: zoom to window (October 1, 2008)">Usable Compiz Fusion: zoom to window</a> (0)</li>
	<li><a href="http://handyfloss.net/2010.03/speed-up-pygtk-and-cairo-by-reusing-images/" title="Speed up PyGTK and Cairo by reusing images (March 18, 2010)">Speed up PyGTK and Cairo by reusing images</a> (2)</li>
	<li><a href="http://handyfloss.net/2009.01/save-hd-space-by-using-compressed-files-directly/" title="Save HD space by using compressed files directly (January 14, 2009)">Save HD space by using compressed files directly</a> (3)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://handyfloss.net/2008.09/making-a-pdf-grayscale-with-ghostscript/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>My backups with rsync</title>
		<link>http://handyfloss.net/2007.01/my-backups-with-rsync/</link>
		<comments>http://handyfloss.net/2007.01/my-backups-with-rsync/#comments</comments>
		<pubDate>Sun, 07 Jan 2007 16:43:00 +0000</pubDate>
		<dc:creator>isilanes</dc:creator>
				<category><![CDATA[Free software and related beasts]]></category>
		<category><![CDATA[en]]></category>
		<category><![CDATA[FLOSS]]></category>
		<category><![CDATA[networks]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://handyfloss.net/?p=164</guid>
		<description><![CDATA[In previous posts I have introduced the use of rsync for making incremental backups, and then mentioned an event of making use of such backups. However, I have realized that I haven&#8217;t actually explained my backup scheme! Let&#8217;s go for it: Backup plan I make a backup of my $home directory, say /home/isilanes. Each &#8220;backup&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>In previous posts I have <a href="/2006.04/backups-with-rsync/">introduced</a> the use of <a href="http://en.wikipedia.org/wiki/Rsync">rsync</a> for making <a href="http://en.wikipedia.org/wiki/Incremental_backup">incremental backups</a>, and then <a href="/2006.07/my-first-use-of-a-backup/">mentioned</a> an event of making use of such backups. However, I have realized that I haven&#8217;t actually explained my backup scheme! Let&#8217;s go for it:</p>
<p><strong>Backup plan</strong></p>
<p>I make a backup of my <tt>$home</tt> directory, say <tt>/home/isilanes</tt>. Each &#8220;backup&#8221; will be a set of 18 directories:</p>
<ul>
<li>Current (last day)</li>
<li>7 daily</li>
<li>4 weekly</li>
<li>6 monthly</li>
</ul>
<p>Each such dir has an apparent <strong>complete</strong> copy of how <tt>/home/isilanes</tt> looked like at the moment of making the backup. However, making use of <a href="http://en.wikipedia.org/wiki/Hard_link">hard links</a>, only the new bits of info are actually written. All the parts that are redundant are written once on disk, and then linked from all the places referring to it.</p>
<p>Result: a 18 copies of a <tt>$home</tt> of 3.8 GB in a total of 8.7 GB (14% of the apparent size of 63 GB, and 13% of 18x the info size, 68,4 GB).</p>
<p><strong>Perl script for making the backup</strong></p>
<p><i><b>Update</b> (Jun 5, 2008): You can find a much refined version of the script <a href="http://isilanes.org/pub/blog/bwr.pl">here</a>. It no longer requires certain auxiliary script to be installed in the remote machine, and is &#8220;better&#8221; in general (or it should be!)</i></p>
<p>Below is the commented Perl script I use. Machine names, directories and IPs are invented. Bart is the name of my computer.</p>
<p><tt><br />
#!/usr/bin/perl -w</p>
<p>use strict;</p>
<p>my $rsync    = "rsync -a -e ssh --delete --delete-excluded";<br />
my $home     = "/home/isilanes";<br />
my $logfile  = "$home/.LOGs/backup_log";</p>
<p>#<br />
# $where -&gt; where to make the backup<br />
#<br />
# $often -&gt; whether this is a daily, weekly or monthly backup<br />
#<br />
my $where = $ARGV[0] || 'none';<br />
my $often = $ARGV[1] || 'none';</p>
<p>my ($source,$remote,$destdir,$excluded,$to,$from);</p>
<p># Possible "$where"s:<br />
my @wheres = qw /machine1 machine2/;</p>
<p># Possible "$often"s:<br />
my @oftens = qw /daily weekly monthly/;</p>
<p># Check remote machine:<br />
my $pass = 0;<br />
foreach my $w (@whats) { $pass = 1 if ($what eq $w) };<br />
die "$what is an incorrect option for \"what\"!\n" unless $pass;</p>
<p># Check how-often:<br />
$pass = 0;<br />
foreach my $o (@oftens) { $pass = 1 if ($often eq $o) };<br />
die "$often is an incorrect option for \"often\"!\n" unless $pass;</p>
<p># Set variables:<br />
if ($what eq 'machine1')<br />
{<br />
# Defaults:<br />
$source   = $home;<br />
$remote   = '0.0.0.1';<br />
$destdir  = '/disk2/backup/isilanes/bart.home.current';<br />
$excluded = "--exclude-from $home/.LOGs/excludes_backup.dat";<br />
$to       = 'machine1';<br />
$from     = 'bart';<br />
}<br />
elsif ($what eq 'machine2')<br />
{<br />
# Defaults:<br />
$source   = $home;<br />
$remote   = '0.0.0.2';<br />
$destdir  = '/scratch/backup/isilanes/bart.home.current';<br />
$excluded = "--exclude-from $home/.LOGs/excludes_backup.dat";<br />
$to       = 'machine2';<br />
$from     = 'bart';<br />
}</p>
<p># Do the job:<br />
unless ($what eq 'none')<br />
{<br />
unless ($often eq 'none')<br />
{<br />
# Connect to the remote machine, and run ANOTHER script there, making a rotation<br />
# of the backup dirs:<br />
system "ssh $remote \"/home/isilanes/MyTools/rotate_backups.pl $often\"";</p>
<p># Actually make the backup:<br />
system "$rsync $excluded $source/ $remote:$destdir/";</p>
<p># "touch" the backup dir, to give it present timestamp:<br />
system "ssh $remote \"touch $destdir\"";</p>
<p># Enter a line in the log file defined above ($logfile):<br />
&amp;writelog($from,$often,$to);<br />
};<br />
};</p>
<p>sub writelog<br />
{<br />
my $from  = ucfirst($_[0]);<br />
my $often = $_[1];<br />
my $to    = uc($_[2]);<br />
my $date  = `date`;</p>
<p>open(LOG,"&gt;&gt;$logfile");<br />
printf LOG "home@%-10s %-7s backup at %-10s on %1s",$from,$often,$to,$date;<br />
close(LOG);<br />
};<br />
</tt></p>
<p>As can be seen, this script relies on the remote machine having a <code>rotate_backups.pl</code> Perl script, located at <code>/home/isilanes/MyTools/</code>. That script makes the rotation of the 18 backups (moving current to yesterday, yesterday to 2-days-ago, 2-days-ago to 3-days-ago and so on). The code for that:</p>
<p><tt><br />
#!/usr/bin/perl -w</p>
<p>use strict;</p>
<p># Whether daily, weekly or monthly:<br />
my $type = $ARGV[0] || 'daily';</p>
<p># Backup directory:<br />
my $bdir = '/disk4/backup/isilanes/bart.home';</p>
<p># Max number of copies:<br />
my %nmax = ( 'daily'   =&gt; 7,<br />
'weekly'  =&gt; 4,<br />
'monthly' =&gt; 6 );</p>
<p># Choose one of the above:<br />
my $nmax = $nmax{$type} || 7;</p>
<p># Rotate N-&gt;tmp, N-1-&gt;N, ..., 1-&gt;2, current-&gt;1:<br />
system "mv $bdir.$type.$nmax $bdir.tmp" if (-d "$bdir.$type.$nmax");</p>
<p>my $i;<br />
for ($i=$nmax-1;$i&gt;0;$i--)<br />
{<br />
my $j = $i+1;<br />
system "mv $bdir.$type.$i $bdir.$type.$j" if (-d "$bdir.$type.$i");<br />
};</p>
<p>system "mv $bdir.current $bdir.$type.1" if (-d "$bdir.current");</p>
<p># Restore last (tmp) backup, and then refresh it:<br />
system "mv $bdir.tmp $bdir.current" if (-d "$bdir.tmp");<br />
system "cp -alf --reply=yes $bdir.$type.1/. $bdir.current/" if (-d "$bdir.$type.1");<br />
</tt></p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://handyfloss.net/2007.01/wifi-with-wpa-under-ubuntudebian/" title="WiFi with WPA under Ubuntu/Debian (January 28, 2007)">WiFi with WPA under Ubuntu/Debian</a> (5)</li>
	<li><a href="http://handyfloss.net/2006.10/ssh-connection-without-password/" title="SSH connection without password (October 6, 2006)">SSH connection without password</a> (1)</li>
	<li><a href="http://handyfloss.net/2010.01/reverse-ssh-to-twart-over-zealous-firewalls/" title="Reverse SSH to twart over-zealous firewalls (January 4, 2010)">Reverse SSH to twart over-zealous firewalls</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://handyfloss.net/2007.01/my-backups-with-rsync/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Editing Wikipedia with mvs</title>
		<link>http://handyfloss.net/2006.10/editing-wikipedia-with-mvs/</link>
		<comments>http://handyfloss.net/2006.10/editing-wikipedia-with-mvs/#comments</comments>
		<pubDate>Wed, 11 Oct 2006 13:26:00 +0000</pubDate>
		<dc:creator>isilanes</dc:creator>
				<category><![CDATA[Application of the Week]]></category>
		<category><![CDATA[en]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Wikipedia]]></category>

		<guid isPermaLink="false">http://handyfloss.net/?p=129</guid>
		<description><![CDATA[I am currently doing some link disambiguation work for the Wikipedia, and as such, I have to find and replace the same strings many times, in many articles. The on-line Wikipedia edition is in general fine, but one would love to be able to use vim, for a task such as the one I&#8217;m taking. [...]]]></description>
			<content:encoded><![CDATA[<p>I am currently doing some <a href="http://en.wikipedia.org/wiki/Wikipedia:Disambiguation_pages_with_links">link disambiguation</a> work for the <a href="http://en.wikipedia.org">Wikipedia</a>, and as such, I have to find and replace the same strings many times, in many articles. The on-line Wikipedia edition is in general fine, but one would love to be able to use <a href="http://en.wikipedia.org/wiki/Vim_%28text_editor%29">vim</a>, for a task such as the one I&#8217;m taking. To do so, one can make use of <a href="http://search.cpan.org/~markj/WWW-Mediawiki-Client-0.31/bin/mvs">mvs</a>.</p>
<p>The <code>mvs</code> program allows us to download a Wikipedia article, save it as a file, then upload it again, after manipulating the file the way we want.</p>
<p>To log in to our Wikipedia account:</p>
<p><code>mvs login -d wikipedia.org -u <em>username</em> -p <em>password</em></code></p>
<p>To download article <em>&#8220;X&#8221;</em> (beware the <code>.wiki</code> extension):</p>
<p><code>mvs update <em>X</em>.wiki</code></p>
<p>We can then edit <em>X</em>.wiki:</p>
<p><code>vim <em>X</em>.wiki</code></p>
<p>Then check it:</p>
<p><code>mvs preview <em>X</em>.wiki<br />
firefox preview.html</code></p>
<p>And finally upload it:</p>
<p><code>mvs commit -m '<em>Your comment goes here</em>' <em>X</em>.wiki</code></p>
<p>For more info, read the <a href="http://en.wikipedia.org/wiki/Wikipedia:Text_editor_support">Wikipedia text editor support page</a></p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://handyfloss.net/2008.09/wikipedia-is-down/" title="Wikipedia is down (September 30, 2008)">Wikipedia is down</a> (0)</li>
	<li><a href="http://handyfloss.net/2007.10/wikipedia-fundraising/" title="Wikipedia fundraising (October 23, 2007)">Wikipedia fundraising</a> (0)</li>
	<li><a href="http://handyfloss.net/2007.06/wikipedia-fever/" title="Wikipedia fever (June 1, 2007)">Wikipedia fever</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://handyfloss.net/2006.10/editing-wikipedia-with-mvs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dynamic file read with Perl</title>
		<link>http://handyfloss.net/2006.07/dynamic-file-read-with-perl/</link>
		<comments>http://handyfloss.net/2006.07/dynamic-file-read-with-perl/#comments</comments>
		<pubDate>Thu, 06 Jul 2006 16:03:00 +0000</pubDate>
		<dc:creator>isilanes</dc:creator>
				<category><![CDATA[Free software and related beasts]]></category>
		<category><![CDATA[en]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://handyfloss.net/?p=86</guid>
		<description><![CDATA[GNU/Linux command-line users, programmers and hackers worldwide have probably come to know and love the wonderful tail shell command, together with cat, head, grep, awk and sed, easily one of the single most usefull commands. A killer feature of tail is the -f (--follow) argument, which outputs the last lines of a file and then [...]]]></description>
			<content:encoded><![CDATA[<p>GNU/Linux <a href="http://en.wikipedia.org/wiki/Command_line_interface">command-line </a> users, programmers and hackers worldwide have probably come to know and love the wonderful <code>tail</code> <a href="http://en.wikipedia.org/wiki/Unix_shell">shell</a> command, together with <code>cat</code>, <code>head</code>, <code>grep</code>, <code>awk</code> and <code>sed</code>, easily one of the single most usefull commands.</p>
<p>A <strong>killer</strong> feature of <code>tail</code> is the <code>-f</code> (<code>--follow</code>) argument, which outputs the last lines of a file <strong>and then keeps waiting for new lines that might keep appearing in the file, and show them on the screen when they do</strong>. This is invaluable to keep track of, e.g., logfiles where new entries are being added all the time, and one does not want to be doing a <code>tail</code> by hand.</p>
<p>Since I am a great fan of <a href="http://en.wikipedia.org/wiki/Perl">Perl</a>, and use its scripts for <strong>anything</strong> short of cooking dinner (but wait&#8230;), I have found myself in situations where I had to <code>tail</code> the last lines of a file. This can be done in several ways:</p>
<div class="codeblock">
<pre>
system "tail $file";
</pre>
</div>
<p>or</p>
<div class="codeblock">
<pre>
my $str = `tail $file`;
print $str;
</pre>
</div>
<p>or with a <code>open()</code> statement, then reading the whole file (or a part), and <code>print</code>ing it. The first example with <code>system</code> is the most &#8220;direct&#8221; one, but reading the file (or a part) into a variable is very handy for doing with it all the nifty things Perl does so well to text strings (substituting, deleting, including, reordering, comparing&#8230;).</p>
<p>However, when <code>tail -f</code> was needed (i.e., keep on tracking the file and operate on the output as it appears), I kept using <code>system</code> calls, and all the formatting had to be done in the <code>shell</code> spawned by the <code>system</code> call, <strong>not</strong> by Perl. This was sad.</p>
<p>So, I was so happy when I discovered a simple trick to make <code>open()</code> read dynamically. There are <strong>better</strong> ways of doing it, more efficiently and correctly, but this one works, and is quite simple. If efficience is vital for you, this is not probably the place to learn about it. Actually, if you look for efficiency, you shouldn&#8217;t be using Perl at all :^)</p>
<p>Example of Perl code that reads dynamically a file &#8220;<tt>$in</tt>&#8220;:</p>
<div class="codeblock">
<pre>
open(INFILE,"tail -0f $in |") || die "Failed!\n";
while(my $line = &lt;INFILE&gt;)
{
  <em>do whatever to $line</em>;
};
close(INFILE)
</pre>
</div>
<p><b>Update:</b> Explanation to the code above:</p>
<p>The <code>open()</code> call pipes the output of the tail command (notice the <code>-f</code> flag. Do a <code>man tail</code> to know more) to the file tag &#8220;INFILE&#8221;. The &#8220;<code>||</code>&#8221; sign is an <a href="http://en.wikipedia.org/wiki/logical disjunction">OR</a>, and means &#8220;do the thing on my right side if the thing on my left didn&#8217;t end successfully (but ONLY in that case!)&#8221;.</p>
<p>Next, we perform a <code>while</code> loop over the lines in the pipe. The &#8220;<code>&lt;INLINE&gt;</code>&#8221; construct extracts elements in <code>INLINE</code>, treating it as an array. As you can see, these elements are assigned to a new variable <code>$line</code>, and the loop continues while <code>$line</code> has some non-false value, i.e. while there are lines in INFILE.</p>
<p>The paragraph inside the curled keys is <a href="http://en.wikipedia.org/wiki/pseudocode">pseudocode</a>, obviously; you put there your code. And, for tidiness, once we exit the loop, and INFILE is exhausted of lines, we close it.</p>

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://handyfloss.net/2008.09/making-a-pdf-grayscale-with-ghostscript/" title="Making a PDF grayscale with ghostscript (September 30, 2008)">Making a PDF grayscale with ghostscript</a> (20)</li>
	<li><a href="http://handyfloss.net/2007.01/why-j2ee-is-complex/" title="Why J2EE is complex (January 3, 2007)">Why J2EE is complex</a> (0)</li>
	<li><a href="http://handyfloss.net/2010.03/speed-up-pygtk-and-cairo-by-reusing-images/" title="Speed up PyGTK and Cairo by reusing images (March 18, 2010)">Speed up PyGTK and Cairo by reusing images</a> (2)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://handyfloss.net/2006.07/dynamic-file-read-with-perl/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

