    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Perl is a Better Sed, and Python 2 is Good</title>
        <link>https://members.accu.org/index.php/journals/2038</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">CVu Journal Vol 26, #5 - November 2014 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c343/">265</a>
                    (10)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c343-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c343+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Perl is a Better Sed, and Python 2 is Good</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 05 November 2014 07:07:56 +00:00 or Wed, 05 November 2014 07:07:56 +00:00</p>
<p><strong>Summary:</strong>&nbsp;Silas S. Brown sweats the differences between tools on common platforms.</p>
<p><strong>Body:</strong>&nbsp;<p>If youâ€™ve done any Unix shell scripting, youâ€™ve probably come across the Stream Editor (sed). Itâ€™s most often used for simple substitution, for example:</p>

<pre class="programlisting">
  for N in *.wav ; do lame &quot;$N&quot; -o &quot;$(echo &quot;$N&quot;|sed
  -e 's/wav$/mp3/')&quot;; done
</pre>

<p>which goes through all <span class="filename">*.wav</span> files and calls the MP3 encoder â€˜lameâ€™ on each one, passing a <code>-o</code> parameter as the filename with the <span class="filename">wav</span> at the end changed to <span class="filename">mp3</span> â€“ itâ€™s the <code>sed -e s/x/y/</code> that does this substitution. <span class="Editor">[The <code>-e</code> argument allows you to provide multiple commands for a single invocation. Ed]</span></p>

<p>In this example, the <code>$</code> at the end of <code>wav</code> is there so that the substitution is made only at the very end of the filename; I donâ€™t want to confuse things if a filename happens to contain â€˜wavâ€™ part-way through. In other situations you might want to add a <code>g</code> after the closing <code>/</code> to globally replace a regular expression many times in a line.</p>

<p>As this example shows, however, you do have to think carefully about your regular expressions (regexps), especially if you donâ€™t know what input youâ€™re going to get. In the above example, if I knew in advance exactly which filenames the command will be working with â€“ say, a particular set of a dozen or so .wav files â€“ and I knew that none of them contain the letters â€˜wavâ€™ except at the very end of the filename, then I wouldnâ€™t need to worry about including the <code>$</code> character in the regexp. (Also, if I knew there were no spaces or other special characters in the filenames, then I wouldnâ€™t have to put quite so many quote marks around everything.) But if, instead of writing a one-liner to do something with a particular set of filenames, Iâ€™m writing a script that Iâ€™ll be using later, or even sharing with other people, then I must be more careful.</p>

<p>Sed is a fairly universal tool: itâ€™s installed â€˜out of the boxâ€™ on nearly every version of Linux, even many small â€˜embeddedâ€™ versions, and also on other Unix systems, such as BSD and its derivative Darwin which runs Mac OS X. So if you use sed for small jobs like this, it should work on all of these systems. At least, thatâ€™s the theory.</p>

<p>In practice, there are a few annoying differences between BSDâ€™s version of sed (on the Mac) and GNUâ€™s version of sed (on Linux). If you develop and test a script on Linux, it might not work on the Mac, and vice versa. For example, on Linux you can include <code>\n</code> in the replacement string to indicate an extra newline should be added, but you canâ€™t do that on the Macâ€™s version of sed.</p>

<p>Yes you can install GNU tools on the Mac, but I like my scripts to be able to run â€˜out of the boxâ€™ to the extent possible, without requiring the installation of too much extra software. Thatâ€™s because I often need to run my scripts on other peopleâ€™s computers (or give them to others to run), so I want to make a reasonable attempt to minimise the amount of system setup thatâ€™s needed before the script will run. (Thatâ€™s also why I tend to be parsimonious about how many third-party libraries my programs rely on: if such libraries wonâ€™t already be there on the system, and arenâ€™t very easy to bundle, then theyâ€™d better be good enough to be worth the hassle of an extra dependency. A large library I want to make extensive use of, like the Tornado web framework in Python, might be a justifiable dependency, but I wouldnâ€™t want to bring in an extra dependency just to save myself from writing a 10-line function â€“ not unless I know for a fact that Iâ€™ll never have to set up this program with its dependencies anywhere else. The trouble with dependencies is you never know when someone will come along with a system on which they donâ€™t compile, or doesnâ€™t give them enough rights to run the installer, or something, and if itâ€™s not your code then itâ€™s that much harder to figure out what to do about it.)</p>

<p>And so we come to perl. Iâ€™m not an expert perl programmer (most of the perl Iâ€™ve done has been making changes to other peopleâ€™s scripts rather than writing my own), but perl does have a very nice (and often overlooked) command-line option to sort-of â€˜emulateâ€™ sed: the <code>-p</code> option. Try:</p>

<pre class="programlisting">
  perl -p -e 's/wav$/mp3/'
</pre>

<p>and youâ€™ll find it behaves just the same as <code>sed -e</code>, except itâ€™s the same across Linux and BSD (and supports things like â€˜newline in replacement textâ€™ on both platforms). Also, you donâ€™t have to put backslashes in front of any parentheses you use (in fact you shouldnâ€™t), which makes your regexps more readable. The other thing to watch for is, if youâ€™re doing multiple substitutions then you should separate them with semicolons rather than supplying additional <code>-e</code> commands as with sed.</p>

<p>Apart from these minor differences to be aware of (which generally go in perlâ€™s favour), <code>perl -p</code> is more or less a â€˜drop-in replacementâ€™ for most uses of sed, except itâ€™s more powerful (and you donâ€™t have to backslash-escape so much) and itâ€™s more likely to work across platforms. So if you find yourself using <code>sed -e</code> in scripts a lot, Iâ€™d recommend being aware of this.</p>

<p>Of course, there will be some â€˜embeddedâ€™ systems out there that have sed but not perl. But generally speaking, perl is quite ubiquitous these days, and it has for some years â€˜settled downâ€™ to a nice stable language thatâ€™s not likely to change under your feet, so it is very well suited for use in shell scripts like this.</p>

<p>What I call a â€˜stableâ€™ language, some people might call â€˜stagnatedâ€™. But I donâ€™t see whatâ€™s wrong with a bit of stability: if you want your code to be portable to many systems â€˜out thereâ€™ with minimum fuss, itâ€™s probably easiest if youâ€™re using a language that has â€˜settled downâ€™ to being pretty much the same everywhere, even if this does mean youâ€™re â€˜living in the pastâ€™ to an extent.</p>

<p>Python 2 is now a nice stable language as well, especially since Python 3 has syphoned off all new development but Python 2 is still (just about) supported for essential bug fixes and security checks. Python 2 is pre-installed on nearly every Linux and Mac OS X machine, is available for all kinds of older systems that Python 3 has yet to be back-ported to â€“ Windows Mobile, Android SL4A, Series 60, EPOC, even RISC OS â€“ and thereâ€™s also a tool to turn a Python program into a standalone Windows executable, including interpreter, which can be run without needing any administrator privileges on the Windows machine (later versions of this tool began to require administrator privileges, which rules out use in a computer lab; I have a nice early version which even lets me update the Windows package from the comfort of Linux without having to go into Windows at all, athough it does mean I canâ€™t add new libraries to it).</p>

<p>Itâ€™s even possible to write code in such a way that it will run on very old 2.x versions of Python, on older systems. For example, for Python 2.2 and earlier, do this:</p>

<pre class="programlisting">
  try: True
  except: exec(&quot;True = 1 ; False = 0&quot;)
</pre>

<p>which defines <code>True</code> and <code>False</code> as variables if the keywords donâ€™t yet exist. And try to avoid writing â€˜string1 in string2â€™ where <code>string1</code> can be more than one character (not supported in versions of Python before 2.3). You could also do:</p>

<pre class="programlisting">
  try: set
  except:
    def set(l):
      d = {}
      for i in l: d[i]=True
      return d
</pre>

<p>to emulate the <code>set()</code> constructor (from a list) on versions of Python before real sets were introduced.</p>

<p>But these days I usually target Python 2.7 if there is no great need to be <em>that</em> multi-platform (i.e. the script Iâ€™m writing will probably not be useful on Series 60 etc, but I still want it to work on any Linux or Mac system from the last few years). Even still, I try to code in such a way that it wonâ€™t be <em>that</em> much of a hassle to back-port to earlier versions of Python 2 if necessary (although if I have to depend on a library like Tornado then thereâ€™s no point even trying to support versions of Python that are older than the library supports â€“ or at least thereâ€™s no point going before the oldest version of Python thatâ€™s supported by the oldest sensible version of the library).</p>

<p>I do remember writing for Python 1.x, and Iâ€™m glad Iâ€™m not doing that any more. But it now seems Python 2 has reached a nice balance of features and stability, and I really donâ€™t see the need to move to Python 3: its advantages are not worth the extra dependency of installing it on every system I want my programs to work on (including older Mac OS X machines). Perhaps a Python 3 enthusiast would like to point out whatâ€™s so good about Python 3? But it had better be amazingly outstanding if I have to insist all my users install it first instead of using whatâ€™s already on their systems.</p>

<p>Incidentally, this year the Ubuntu distribution of Linux declared an intention to eventually ship only Python 3 by default, and to make Python 2 an optional package. This has not yet come to fruition, but if it does, it still wonâ€™t help non-Ubuntu distributions, or BSD, especially all the older Mac OS X machines that for various reasons might not be upgradable to whichever future version of Mac OS X actually ships Python 3 by default (as far as I know none of the existing versions of Mac OS X do this). In the current climate, if Ubuntu were to ship Python 3 by default then Iâ€™d just tell Ubuntu users to install the Python 2 package, because Iâ€™m concerned about all those other systems as well, some of which donâ€™t have easy-to-use package managers like Ubuntu does. But I donâ€™t understand why anyone would want to â€˜kill offâ€™ Python 2 anyway: why canâ€™t they leave it alone like Perl 5 as a super-stable ubiquitous tool? Yes Iâ€™m all for playing with new languages, but not when Iâ€™m trying to write something thatâ€™s supposed to run everywhere (well, not unless I can first compile my code into a more widespread language to ship, but thatâ€™s not the case with Python â€“ if you want it to run somewhere then you need a suitable version of Python â€˜on siteâ€™ there, and that usually means Python 2).</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
