renaming batches of files in linux

I often need to rename many files at one time. Usually I just want to add an extension to the end of the name. The best way I have found is with the rename command. I have a few .rb files which I want to rename as .rb.erb files.

[code]
-rwxr-xr-x 1 philip philip 218 2010-10-22 17:19 message_broadcaster.rb
-rwxr-xr-x 1 philip philip 90 2010-10-22 17:19 message_group_criteria.rb
-rwxr-xr-x 1 philip philip 2180 2010-10-22 17:19 message.rb
-rwxr-xr-x 1 philip philip 193 2010-10-22 17:19 message_recipient_group.rb
-rwxr-xr-x 1 philip philip 134 2010-10-22 17:19 message_recipient.rb
-rwxr-xr-x 1 philip philip 427 2010-10-22 17:19 message_template_owner.rb
-rwxr-xr-x 1 philip philip 661 2010-10-22 17:19 message_template.rb
[/code]

Running the rename command with a -n will show you files that will be changed without actually running the command. Let’s take a look at potential changes:
[code]rename -v -n ‘s/^([a-z_A-Z]+\.rb)$/$1.erb/’ *.rb[/code]
[code]
message_broadcaster.rb renamed as message_broadcaster.rb.erb
message_group_criteria.rb renamed as message_group_criteria.rb.erb
message.rb renamed as message.rb.erb
message_recipient_group.rb renamed as message_recipient_group.rb.erb
message_recipient.rb renamed as message_recipient.rb.erb
message_template_owner.rb renamed as message_template_owner.rb.erb
message_template.rb renamed as message_template.rb.erb
[/code]

Now we just take the -n off of the command and rerun it. Now we can relist the files and see the changes:
[code]ls -al[/code]
[code]
-rwxr-xr-x 1 philip philip 218 2010-10-22 17:19 message_broadcaster.rb.erb
-rwxr-xr-x 1 philip philip 90 2010-10-22 17:19 message_group_criteria.rb.erb
-rwxr-xr-x 1 philip philip 2180 2010-10-22 17:19 message.rb.erb
-rwxr-xr-x 1 philip philip 193 2010-10-22 17:19 message_recipient_group.rb.erb
-rwxr-xr-x 1 philip philip 134 2010-10-22 17:19 message_recipient.rb.erb
-rwxr-xr-x 1 philip philip 427 2010-10-22 17:19 message_template_owner.rb.erb
-rwxr-xr-x 1 philip philip 661 2010-10-22 17:19 message_template.rb.erb
[/code]

Easy.

Thor – add jQuery example

I create new Rails3 apps quite frequently. As you know, Rails is packaged with Prototype- the Javascript library. I prefer to use the jQuery library. So, I need to manually add the library file. I can copy it from another project but that requires me to type a long command such as
cp ../../source.../file ./public/javascripts

There are other problems. Rails projects have a ‘rails.js’ file which needs to be swapped out with a jQuery compatible file. Also, we need to include the Javascript files inside our html head tag. To save some time I decided to create a new Thor task to accomplish all this work. Once the task is created I can simply run the following command inside the root directory of any new Rails app:

thor fbp_tools:jQuerify

fbp_tools is the name of my custom collection of thor tasks. Here is what happens when the jQuerify task runs:

[code]
…$ thor fbp_tools:jQuerify
jQuery
create public/javascripts/jquery-1.4.3.min.js
create public/javascripts/rails.js
inject app/views/layouts/application.html.haml
NOTICE: please open and verify your modified layout
[/code]

We can see that 2 files were created in correct Rails directories. Also, the application.html.haml layout template file was opened and modified (the term for this is “inject”). Finally a notice to the user suggesting the verification of the modified layout file due to the fact that .haml template files require proper white-space alignment. (I’ll post something about the amazing haml system in a future article.)

What happens if we run it again?

[code]
…$ thor fbp_tools:jQuerify
jQuery
identical public/javascripts/jquery-1.4.3.min.js
identical public/javascripts/rails.js
inject app/views/layouts/application.html.haml
NOTICE: please open and verify your modified layout
[/code]

Since the files are identical, nothing happens. Also, the inject procedure doesn’t need to do anything because it detects the previous edit.

Thor – an intro

Thor is a simple and efficient tool for building self-documenting command line utilities. It removes the pain of parsing command line options, writing “USAGE:” banners, and can also be used as an alternative to the Rake build tool. The syntax is Rake-like, so it should be familiar to most Rake users.

I have built a corporate security model. When I say “security model” I am talking in a generic fashion. So what is it? Well it is ER-model for a relational database which allows me to record people objects, their web user objects, the organization objects that they belong to, the role objects for web app usage rights, and many other objects related to general web application use by humans.

When implementing such a model in an MVC architecture like RubyOnRails there will be many files located in various directories. This is not a big problem at all until you decide that you want to use this security model’s functionality in other RubyOnRails web applications. The obvious solution is to build some kind of plugin. Indeed, frameworks such as RubyOnRails do provide some sort of support for building plugins that can be reused.

In the Ruby development world we have the excellent Rake build and automation tool. However, this article will explore Thor which can be considered a kind of “next generation” Rake tool.

I’ll keep this post short and explore more details at a later time. For now let’s take a look at my Thor “configuration.”

[code]
…dev/_thor/testarea$ thor installed
Modules Namespaces
——- ———-
authena authena
fbptools fbp_tools

authena
——-
thor authena:install NAMEs files #
thor authena:removes installed files #

fbp_tools
———
thor fbp_tools:install NAME # installs files
thor fbp_tools:uninstall NAME # removes installed files

[/code]

We see that there are two Thor packages installed in my environment. I built them both. Authena is the name of the Thor task package which installs and uninstalls the security model files. fbp_tools is the package which installs some utility files which I use in many Rails apps.

Both packages install and remove files into various directories such as the “models”, “views”, and “controllers” directories.

Let me finish with a teaser showing you what happens when we install the Authena package. Next time, I’ll dig into the code a bit deeper.

[code]
…testarea$ thor authena:install
create app/models/accessibility.rb
create app/models/address.rb
create app/models/contact.rb
create app/models/organization_binding.rb
create app/models/organization.rb
create app/models/person.rb
create app/models/role.rb
create app/models/software_application.rb
create app/models/user.rb
create app/views/accessibilities/_access.html.haml
create app/views/accessibilities/change_user_role_state.js.rjs
create app/views/accessibilities/invalid_state_change.js.rjs
create app/views/layouts/admin.html.haml
create app/views/layouts/organizations.html.haml
create app/views/layouts/user_sessions.html.haml
create app/views/layouts/users.html.haml
create app/views/organizations/edit.html.haml
create app/views/organizations/_form.html.haml
create app/views/organizations/index.html.haml
create app/views/organizations/new.html.haml
create app/views/organizations/show.html.haml
create app/views/people/cancel_access_edit_area.js.rjs
create app/views/people/edit.html.haml
create app/views/people/new.html.haml
create app/views/people/_roles_by_user.html.haml
create app/views/people/show.html.haml
create app/views/people/destroy.html.haml
create app/views/people/index.html.haml
create app/views/people/_people_list.html.haml
create app/views/people/show_access_edit_area.js.rjs
create app/views/roles/_action_menu.html.haml
create app/views/roles/index.html.haml
create app/views/roles/show.html.haml
create app/views/users/_accessibilities_for_users.html.haml
create app/views/users/change_user_teacher.js.rjs
create app/views/users/_form.html.haml
create app/views/users/show_assign_to_teacher_area.js.rjs
create app/views/users/cancel_assign_student_to_teacher_area.js.rjs
create app/views/users/edit.html.haml
create app/views/users/new.html.haml
create app/views/users/show.html.haml
create app/controllers/accessibilities_controller.rb
create app/controllers/admin_controller.rb
create app/controllers/managers_controller.rb
create app/controllers/organizations_controller.rb
create app/controllers/people_controller.rb
create app/controllers/roles_controller.rb
create app/controllers/users_controller.rb
create app/helpers/accessibilities_helper.rb
create app/helpers/admin_helper.rb
create app/helpers/managers_helper.rb
create app/helpers/organizations_helper.rb
create app/helpers/people_helper.rb
create app/helpers/roles_helper.rb
create app/helpers/user_sessions_helper.rb
create app/helpers/users_helper.rb
create db/schema.rb
[/code]

As you can image it would be very time consuming to copy these files manually every time you want to add this module to your MVC application!!!

Removing this security model’s files is quite easy as well:

[code]
…/testarea$ thor authena:uninstall
remove app/models/accessibility.rb
remove app/models/address.rb
remove app/models/contact.rb
remove app/models/organization_binding.rb
remove app/models/organization.rb
remove app/models/person.rb
remove app/models/role.rb
remove app/models/software_application.rb
remove app/models/user.rb
remove app/views/accessibilities/_access.html.haml
remove app/views/accessibilities/change_user_role_state.js.rjs
remove app/views/accessibilities/invalid_state_change.js.rjs
remove app/views/layouts/admin.html.haml
remove app/views/layouts/organizations.html.haml
remove app/views/layouts/user_sessions.html.haml
remove app/views/layouts/users.html.haml
remove app/views/organizations/edit.html.haml
remove app/views/organizations/_form.html.haml
remove app/views/organizations/index.html.haml
remove app/views/organizations/new.html.haml
remove app/views/organizations/show.html.haml
remove app/views/people/cancel_access_edit_area.js.rjs
remove app/views/people/edit.html.haml
remove app/views/people/new.html.haml
remove app/views/people/_roles_by_user.html.haml
remove app/views/people/show.html.haml
remove app/views/people/destroy.html.haml
remove app/views/people/index.html.haml
remove app/views/people/_people_list.html.haml
remove app/views/people/show_access_edit_area.js.rjs
remove app/views/roles/_action_menu.html.haml
remove app/views/roles/index.html.haml
remove app/views/roles/show.html.haml
remove app/views/users/_accessibilities_for_users.html.haml
remove app/views/users/change_user_teacher.js.rjs
remove app/views/users/_form.html.haml
remove app/views/users/show_assign_to_teacher_area.js.rjs
remove app/views/users/cancel_assign_student_to_teacher_area.js.rjs
remove app/views/users/edit.html.haml
remove app/views/users/new.html.haml
remove app/views/users/show.html.haml
remove app/controllers/accessibilities_controller.rb
remove app/controllers/admin_controller.rb
remove app/controllers/managers_controller.rb
remove app/controllers/organizations_controller.rb
remove app/controllers/people_controller.rb
remove app/controllers/roles_controller.rb
remove app/controllers/users_controller.rb
remove app/helpers/accessibilities_helper.rb
remove app/helpers/admin_helper.rb
remove app/helpers/managers_helper.rb
remove app/helpers/organizations_helper.rb
remove app/helpers/people_helper.rb
remove app/helpers/roles_helper.rb
remove app/helpers/user_sessions_helper.rb
remove app/helpers/users_helper.rb
remove db/schema.rb
[/code]

Terminal Emacs keybindings

I noticed something new in the command terminal on my Ubuntu upgrade. First old news: the command line uses some Emacs editor shortcut key combos:

ex: Ctrl F – forward one char; Ctrl B – backward one char; Ctrl A – beginning of line; Ctrl E – end of line and a few others

ex: Ctrl P- previous command in cache, Ctrl N – Next command in cache
(type “ls -al” then ” ls” then “echo”…. now Ctrl P and Ctrl N cycle through the commands)

But here is something recently added:
Ctrl R – initiates a regular expression search in reverse through all the previous commands in the cache.
So hit Ctrl R and then type ls … you will see the command starting with “ls” … hit Ctrl R again and you will see the next one starting at “ls”…
Hit Ctrl G to cancel the prompt. in Emacs Ctrl G is always the prompt cancel.

Give it a try.