ShellScriptCorner

Help & Guidance to Shell Scripting with TM

(converted from old Wiki by Eric Hsu on 12-15-04)

This page is hopefully going to be filled with valuable examples of how to use various shell / UNIX commands within TM to get the results we all dream of.

My hope is that this page could become a good resource for us non-geeks that don't understand the geekish man files and online tutorials out there on the web and in OS X.

If you understand how to use sed, awk, bash, perl etc etc. then perhaps you could write a simple sample of a real life example that is easy to understand for someone new to it to use.

Example: Starting your computer

  1. Ensure the computer is plugged in to the mains.
  2. Look for a start button somewhere on the front or the back...
  3. ...

OK, I know that was a bit extreme, but please do NOT take things for granted when you create your examples here. You and thousand others may know this by heart, but I and many others don't! Many of us are designers - visual people - that have been 'forced' into programming, rather than the other way around.

Thanks for your time.


Add/Remove Comment Characters

by Avram?

Here are a couple of shell commands to add or remove characters from the beginnings of lines of a block of text. I'll use the hash symbol (#), used as a comment character in Perl, for an example:

To comment out a block of Perl code:

	sed "s/^/# /"

This adds a hash followed by a space to the beginning of each line. To use it, select the text block, then choose Filter Through Command... from the Text menu. In the resulting dialog, choose the Selection radio button in the Input area, and Replace Selection in Output. Type that bit of shell code into the Command field, and hit the Execute button, and it ought to work.

To strip off the comment characters, use this:

	sed "s/^#\s*//"

That'll strip off a hash plus as many space characters follow it from the beginnign of each line. This could remove your indentation if you use spaces to indent; it won't remove tabs.

And you can add these to the Commands menu. Just use the Edit Menu... command (last command in that menu).


Toggle Comment Status (Perl version)

by Eric Hsu

I am more comfortable writing in Perl than in pure shell script. Luckily, you can execute any perl program as a shell script by invoking it as <pre>perl -e '<script>'</pre> Here's an example. I like to have a 'toggle comment' feature instead of having to remember two key commands for comment/uncomment. So I wrote a simple Perl script to first check whether it's a comment or not, and either commenting or stripping comments on all lines of the selection in response :

	perl -e 'while(<STDIN>){unless ($com) {/(\S)/;
	if ($1 eq "#") {$com=1} else {$com=2};};
	if ($com==1){s/\#\s+//;} else {s/(\S)/# $1/}; print;}'

(To install in TM, remove all returns, set as a command with standard input set to 'selection' and output to 'replace selection')

The perl script itself with comments:

	while(<STDIN>){  # read in each line of the selection, put in $_
	unless ($com) { 
		# unless we know the comment status ($com not 0), 
		# check first non-space character
		/(\S)/; #find it, put it in $1 
		if ($1 eq "#") {$com=1} else {$com=2};}; 
		# if the first char is # then it's a comment; else it's not
		if ($com==1){s/\#\s+//;} 
		# if it's a comment, strip all first # with following whitespace 
	else {s/(\S)/# $1/};  
		# otherwise, precede the first char with "# "
		# If we just replaced start of line (^) with #, 
		# that would mess up indenting whitespace.
		print;}  # print $_ back to TM

Hope that's helpful. If you want to substitute # with funny characters like "//" you may have to escape them with \'s.

A version using "//" that works for Otto:

	perl -e 'while(<STDIN>){
	    unless ($com) {
	        /(\S\S)/;
	        if ($1 eq "//") {$com=1} 
	        else {$com=2};
	    };
	    if ($com==1){s/\/\/\s*//;} 
	    else {s/(\S)/\/\/ $1/}; 
	    print;
	}'</pre>

Sorting Lines

by Avram?

I just discovered that the built-in Sort macro (Automation > Replay Macro > Sort) sorts in ASCII order. ASCII is the (well, a, but it's a ubiquitous) standard for text in computing; each character has a numeric code associated with it. Thing is, all the capital letters have one set of numbers, followed by all the lower-case letters -- A through Z are 41 through 90, and a through z are 97 through 122. And then there are some non-alphabet characters in 91-96.

Like I said, Textmate's built-in Sort macro sorts in ASCII order, so Zebra comes before aardvark, and [walrus] comes in between them. Fortunately, you can define your own case-insensitive Sort command using the Unix sort shell program. It�s even easier than the sed command above. Just select the lines you want sorted, choose Filter Through Command..., and use this command:

	sort -f

There are other switches (that's what you call those letters that follow dashes in command-line programs) you can add in. -r does a reverse-order sort, -u deletes repeated lines, and -b ignores and whitespace (spaces, tabs) at the beginnings of the lines. You can bundle these all in after a single dash, so to do a reverse case-insensitive sort that removes duplicate lines, do this:

	sort -fur

Use Ruby to Do Regular Expression String Substitution in Filter Through Command

by riles?

  • Highlight the text you wish to execute a regular expression search and replace on.
  • Right click your mouse and select 'Filter through Command...'.
  • For Input choose 'Selection'
  • For Output choose 'Replace Selection'
  • In the command text field enter:

$TM_RUBY -e "print ENV['TM_SELECTED_TEXT'].gsub(/yoursearch patternhere/, 'your replacement here')"

$TM_RUBY is an environment variable you can define under Preferences > Advanced > Shell Variables. It should point to your ruby installation.

The search pattern will accept a regular expression (a whole topic in itself) and the replacement string can contain a string, back reference, or a backticked inline command, e.g., `date`.