rr – 1.1 – In Place Edits and Multiple Files

Less then 48 hours after rr becomes 1.0 it gets a few very handy improvements!

In place modification of files is activated via the –modify (or shorthand -m) option. This means that you can bypass any output redirection and just go straight to modifying the original file. This feature does use filename.tmp as a temp file which it later renames to the original filename. Again if no filenames are specified then input is expected to come from STDIN and therefore the new –modify option will be ignored in this special case.

Another original goal of mine was adding support for multiple filenames. Specifically so that useful shell tricks like *.txt file globbing would work nicely with rr. Well support has been added and it works great with the new –modify option.

The usage message has been cleaned up a bit but here is the very basic usage for all new people.

usage: rr [options] find replace [filenames]
       rr [options] s/find/replace/ [filenames]

I wanted to point out a rather hidden feature. The way I implemented the options is that the ARGV array is actually parsed first for all options and then removes the options before going on to parse the find, replace, and filename arguments. This means that your options can go anywhere on the command line so long as they start with a -.

This presents 1 problem, a workaround, and a question for users. Using the second form of usage, where the find and replace portions are separate argument if your regex or replacement text starts with a “-” the script will interpret it as an option. You can avoid this by using the s/find/replace/ usage (or putting the regex in /regex/ format, which is allowed). But really this boils down to deciding whether or not I am being too liberal with my command line arguments. Since this is a very big fringe condition with a workaround I am going to allow options to be placed anywhere, allowing you to bring up the last command in bash with the up arrow and adding an option to the end of your rr command (like the new -m) to repeat your last command with an option much easier.

rr is always free, Try It Out:
rr – Current Version Download
rr – changelog.txt – Click Here

$ gem install regex_replace

rr – Regex Replace on a File – SotD

I was frustrated with regular expression find/replace programs that only did line processing. This was because often I had find/replace needs that spanned multiple lines. Programs like grep, ack (which I recently found and is really, really very awesome for searching code), and sed were easy enough to use for basic needs. But again, when it came to multiple line pattern matching both fell short of my needs.

My solution was to write my own script to parse an entire file as a single string and do my find/replace bidding. The cons being liberal use of memory and a few hundredths of a second longer then the usual find/replace algorithms seemed insignificant to the pros of a multi-line capable find/replace using a regular expression with the capability of using back references (like \1) to incorporate captured groups from the regex into the replacement text.

So, without further ado I present rr.

I am hopeful for some public criticism to help me bring rr up from its current version of 0.9 to a landmark 1.0. The ruby script weighs in at 100 lines but really under 50 are code and the rest is comments, whitespace, or the usage string. Speaking of usage, here is what it currently [v0.9.0] looks like:

usage: rr [options] find replace filename
  find     - a regular expression to be run on the entire file as one string
  replace  - replacement text, \1-\9 and \n are allowed
  filename - name of the input file to be parsed

options:
  --line or -l    process line by line instead of all at once (not default)
  --case or -c    makes the regular expression case sensitive (not default)
  --global or -g  process all occurrences by default (this is already default)

negated options are done by adding 'not' or 'n' in switches like so:
  --notline or -nl

example usage:
  The following takes a file and doubles the last character on each line
  and turns the newlines into two newlines.
  rr "(.)\\n" "\\1\\1\\n\\n" file

More then likely this will undergo a lot of changes. A quick list of my current ideas include:

  1. If no filename is provided take input from STDIN. Multiple files can be handled by piping the `cat` of multiple files through rr.
  2. Better switch structure, although right now I don’t have any idea what that is

I’ll throw a test scenario at you. I had tabulated data in a file but each row was split across multiple lines. Now this wasn’t the only data in the file but I’ll present you with a simplier version here: [in.1]

Product A  12.99
           2001
----
Product B   1.99
           1997

Here you can see that I can’t just replace every other newline. What I want to actually do is replace newlines where there was a digit followed by a newline, some whitespace and another digit. I ran this through my script:

> rr "(\d)\n\s+(\d)" "\1  \2" in.1 > out.1

And I got the output I wanted: [out.1]

Product A  12.99  2001
----
Product B   1.99  1997

Even cleaner results can be seen by running a more advanced regex to remove the extra lines:

> rr "(\\d)\\n\\s+(\\d.*?\\n)(-+\\n)?" "\\1  \\2" in.1
Product A  12.99  2001
Product B   1.99  1997

So what are you waiting for? Download the script, add it to your bin directory, give it a test run, and tell me how you want it improved!

rr – Most Recent Version – Download

Thanks!

Upcase a File – SotD

I just came up with something fun. Sotd – Script of the Day. Whenever I find/make a good script I will try to include it here, with the tag, and some fun content to work around it. Today’s script is the simple task of converting an entire file to uppercase. To standardize solutions I will say the current file is in.txt and we want the output file to go to out.txt. Here goes…

This simple task came from a question posted on Experts Exchange in the Scripting zone. Specifically Perl, however I putzed around with Perl and couldn’t quickly figure out what my print uc($_); was doing wrong, so I moved on to try my luck with Ruby. One minute without a need to look up any functions and 30 seconds of it not realizing I was still in the irb… and I had my Ruby solution:

> ruby -e "puts File.read('in.txt').upcase" > out.txt
> ruby -ne 'puts $_.upcase' < in.txt > out.txt

Which helped me produce the perl solution:

> perl -ne 'print uc' in.txt > out.txt

But I figured there had to be an easier way. I decided to manipulate tr///, transliterate, to convert lowercase characters to uppercase with the following one-liner piping the input file through tr and redirecting the output:

> cat in.txt | tr a-z A-Z > out.txt

I was pretty happy with it. How would you have done it?

A Unique Unix Tutorial

Thats right. You’ve all read tutorials. They range all over the place: boring, brief, detailed, useless, inspiring, the list goes on. There are those that are too technical, that you don’t understand until you look back at them at a later date. In the case of Unix and Linux the majority of the tutorials are like that. They are just reworded man pages. Many people turn away from *nix because of this gap in technical familiarity. My Unix tutorial aims to change this.

I have read a number of tutorials and I find the best are the ones that include you, the reader, in them. You are participating in the tutorial. Often there is a story, or some creative aspect that brings you into the tutorial. You are learning in an entertaining way. For first timers this can make all the difference.

My tutorial also gives tips and tricks for using the terminal. They are the kind of tricks that make using the console much easier, but they are the tricks that you often don’t know unless someone shows you. I hope that my tutorial at least gives insight to newer Unix/Linux users as they take the leap into a new realm.

Please take a look and offer your feedback to help me improve the tutorial. I now present my Unix Tutorial.

I would like to point out that the tutorial happened to be a college project that I recently decided to turn into a reality. I have been and will be refurnishing the tutorial with improvements (sIFR), more rich content, while still maintaining my original goals and objectives.

Inspiration: A rather stimulating Ruby tutorial that wraps you inside a rather creative story, with “synergy and cartoon foxes.”

search