Blog 1

Random Talk on Random Thoughts

Oneline Perl

| Comments |

Motivation

Knowing some regular expressions in Vim, I hope to apply these concepts to Perl so that I can search and replace some simple strings directly in base without having to open the editor.

As a Vim user, the class of special characters in Perl is more natural than that of sed.

Problem

In the previous post, the list of Git commit messages containing the string “HTTPS” is the main focus. However, the alignment of this list isn’t good: in the column representing the day, the data can be either one or two digit. Though I can still extract information with awk '{print $[col_num]}', it’s better to fix the alignment.

$ git log -2 --grep="HTTPS" --pretty="%h %cd %s"
7400582 Sun Mar 20 20:19:47 2016 +0800 Updated my Rakefile with HTTPS
b6f4f1f Mon Feb 8 00:45:02 2016 +0800 A new article about Flair, Octopress and HTTPS

Start using Perl

Searching “perl intro” online, one can easily find some basic Perl scripts. I tried to issue some simple one-line Perl command to save time, but I couldn’t easily find them. Thanks to a webpage by Philippe Bruhat, I managed to starting using Perl. I jot them down here.

$ perl -e 'print "hello \n"'  # single quote outside
hello
$ perl -e "\$str='abc'; print \$str;"  # escape $, no EOL
abc
$ perl -e "$str='test'; print $str.'\n';"  # not desired
test\n
$ perl -e '$str="test"; print $str."\n";'  # want newlne
test

The -e flag above stands for “execute”.

Read from external command

Unluckily, I didn’t know how to use system() nor backticks to pass output of a command into Perl. After trying a few search keywords, “perl oneline read command output” worked best for me. It was quite uncommon that I found the eighth result useful. In the article Perl One-liners, I found out the answer.

$ for (( i = 1; i <= 10; i++ )); do
  echo $i
  done | perl -e 'while (<>) {s/(?<!\d)\d{1}(?!\d)/0$&/; print $_}'
01
02
03
04
05
06
07
08
09
10

In fact, the flag -n can be used to replace the while (<>) {...} loop. The -p flag has the function of -n but also prints the output. I learnt them from Git manual web page for git-log.

Solution

Combine the above observations together.

$ git log -2 --grep="HTTPS" --pretty="%h %cd %s" \
  | perl -pe 's/(?<=\u\l\l )\d{1}(?= )/0$&/'
7400582 Sun Mar 20 20:19:47 2016 +0800 Updated my Rakefile with HTTPS
b6f4f1f Mon Feb 08 00:45:02 2016 +0800 A new article about Flair, Octopress and 
HTTPS

Lessons learnt

  1. Perl: Apart from the above syntax, I’ve also learnt to use $& and \b in the replacement. This is the Perl counterpart of & and \< or \> in Vim respectively.
  2. Git: In git log and git show,
    • --name-only: suppress the diff hunk
    • --pretty=format: display nothing
    • format vs tformat: t stands for “terminator” (a.k.a. EOL)

    Each of each flags seems to be useless. Nevertheless, when combined together, they help extract the edited files in a particular commit.

  3. Posting long commands in a blog entry

    From the two codeblocks explaining the difference between format and tformat in the Git manual, I understand that it’s better to end each line with a backslash, then continue with the command. In bash, a > is then automatically inserted at the beginning of each line. This is carried from the shell to the source file of the blog article by copy and paste. I used to think that it’s good to keep this so that this and the Ubuntu font will give a sense of reality to the reader. However, this also causes inconvenience to those who want to try this command. From now on, I won’t include this character anymore at the beginning of a long command exceeding 80 characters. I will replace it with a white space instead.

Comments