Monthly Archives: March 2008

New Version of Inkscape!

After by last post, I checked to see if the new version of Inkscape was released yet.

It has been! Version 0.46 at http://www.inkscape.org/. I installed Ubuntu Gutsy and checked some of my annoyances, which are…gone! It is not perfect, but it is much better. It remembers file paths better and the Fill and Stroke dialog is now docked in the main program window. Everything I’ve tried has been a little bit better. Nice job Inkscape crew!

New Banner Ad Created with Inkscape

I just finished a new banner ad for my wife’s dream interpretation site, MyDreamVisions.com.

I did the ad using Inkspace under Ubuntu. Open source drawing programs have come a long way. The current version of Inkscape works pretty well. With a little thought, I can create just about any image I can imagine (the limiting factor, in my case). The next version is a major upgrade and is adding a whole bunch of new features. I hope they are going to improve the user interface, which is a bit of a hodgepodge. Things pretty much work, but there are odd bugs and inconsistencies throughout.

But, like I said, it works well enough and it is possible to draw what I want to.

Here is the banner ad I made:

Mac OS/X Bash Shell

Most Mac users do not have an interest in the Unix shell (running in Terminal). The Mac was carefully an exhaustively developed so an Apple user would not require it. The question is, could a more advanced user enjoy using the shell? I think, yes.

Most things are done very efficiently using the Mac’s graphical interface. Searching for files, opening them, copying them…all easy and efficient. Spotlight works great. But, what if you want to do something with every file found in a search? That is an example of when good old Unix shell commands or shell scripts (little programs written to run on the Bash shell) are extremely useful.

How to Open Terminal

Terminal is the program that the Unix shell runs in. To open Terminal, use Spotlight. Type command-spacebar (hold down the command key and press the spacebar) and enter “terminal” in Spotlight. Select Terminal from the results list. Note that the command key is the one that says “command” and has a cloverleaf looking icon – it is next to the spacebar.

Or, use Finder and locate Terminal in the directory: /Applications/Utilities/

Groundwork

Current Macs use a version of the Bash shell. This is the most common type of Unix shell. Most of what works generally in common versions of Unix, works on the Mac. So, when you want to use Google to find a command, or how to use a command, adding the word “unix” usually helps. If you are going to use less common parameters, make sure to also check out specific OS/X reference pages, because there are differences from one Unix to another.

Case is important. Filenames, directories…just about everything is case sensitive. Therefore, you could have “photos” and “Photos” in the same directory. “ls” is the list files command. “LS” and “Ls” are not!

Switches: In Unix, switches are demarcated with a hyphen (“-“). In Windows/DOS a slash character is used (“/”). When more than one switch is selected, they can be strung together after the hyphen. For instance, with the “ls” (list files) command, if you wanted to use both the “-a” (all files, including hidden files) and “-l” (long listing format) switches, the command line would be:

ls -al

Globing: Globing is the term for Unix-style “wildcards”. These are handled completely differently than they are in Windows/DOS. In Windows, the program being executed is responsible for expanding wildcard characters. In Unix, the shell expands the filename specified. The Unix globing characters are:

? Matches any one character in a filename.
* Matches any character or characters in a filename.
[ ] Matches a character within the brackets.
- A hyphen used within [ ] denotes a range of characters.
~ A tilda at the beginning of a filename expands to be the user’s home directory.

Note the absence of a “.” period character. Unix does not have the equivalent of Windows-style filename extensions.

A Starter Set of Commands

Here are a few shell commands to start with.

ls List files. This is sort of like DIR in DOS.
cd Change directory.
mkdir Make directory.
rmdir Remove directory.
cat Concatenate file(s) to standard output. Can be used to display file contents.

Jump in and get your feet wet. Next, I’ll revisit this topic and expand on it a bit.

Unix Equivalent of DOS COPY CON

This is an answer to a question I got by e-mail.

“A lot of times I need to create a quick text file, like a script (like I used to create Batch files in DOS/Windows). I used to use COPY CON for this. How can I do this in Unix?”

This is just as easy in Unix. Instead of COPY CON filename, use cat >filename. As before enter the text for the file. Then close the file by hitting enter one more time and entering control-D.

Remember, if you are creating a shell script, make the file executable with chmod +x filename.

Also, to execute the script, remember to include the path to the script, even if you are in the same directory as the script, like this ./scriptname.

Taxpayer Demands Competent Government

It does not seem as though voting for one party or the other affects the basic competency of our government.

Is it too much to ask for? No it is not.

It is our duty to the next generation to leave a better world than the one we were born into.
The science of government it is my duty to study, more than all other sciences; the arts of legislation and administration and negotiation ought to take the place of, indeed exclude, in a manner, all other arts. I must study politics and war, that our sons may have liberty to study mathematics and philosophy. Our sons ought to study mathematics and philosophy, geography, natural history and naval architecture, navigation, commerce and agriculture in order to give their children a right to study painting, poetry, music, architecture, statuary, tapestry and porcelain. – John Adams

I wish that it was not necessary to concern myself with government. I just want to live my life, love my wife, write what I like, play music, write some code and make things. But, my morning paper sickens me with my government meddling endlessly in my life, my rights, my peace of mind and doing things in my name, with my money, that are stupid and counter to American interests.

The Adams quote I heard while watching the current HBO series. Embedded therein is the distaste for needing to understand and improve government, out of duty to his country and his children. Just a hard working and intelligent man, doing what he can in the face of loss of liberty and freedom.

Something like XCOPY on the Mac?

This is an answer to a question about how to recursively copy newer files from one directory to another with a Mac. By “recursively” I mean including sub directories. …Oh, and this is using the Unix shell in Terminal. (Remember, the easy way to get to Terminal is Command-Spacebar to open Spotlight and then type Terminal and open it.

xcopy C:/source X:/destination /e/s/d/y

In Windows, the above command does this and does not prompt when overwriting files.

My first thought was “cp -fuRp * /destination” but there is no -u parameter in OS/X! Egad.

So, then I thought of “rsync” and that seems to do the job:

rsync -aruv * /destination

This example assumes the directory you are copying from is the working directory.

-a Archive mode – retains file settings including dates
-r Recursive – subdirectories
-u Update – only copy newer files
-v Verbose

Remember! Don’t use “*.*” in unix. There are no Windows-style file name extensions.

Yes, it is different from Windows. Yes, it has to be learned to be used. Keep in mind that you had to expend effort to learn DOS/Windows commands and that Unix isn’t going away – what you learn will continue to be useful are a long time.

Mass File Renaming in Unix or Linux

Here’s a quick script that you can use to rename a bunch of files. It will rename all of the files in the working directory that have certain text to something else that you specify. For example, when you have a group of photos from a digital camera with sequentially numbered files like “IMG1.JPG, IMG2.JPG, IMG3.JPG…etc.” that your would like to be called “2008-feb-baseball-1.jpg, 2008-feb-baseball-2.jpg, 2008-feb-baseball-3.jpg…etc.”.

The Code

Create a text file called massren with this as the content:

#!/bin/sh
for filename in *$1*
do
mv -fT “$filename” `echo $filename | sed -e “s/$1/$2/”`
done

Then, make the file executable with:

chmod +x massren

Usage

masren textfrom textto
Where: textfrom is the text to replace in each file name.
textto is the new replacement text.

Example

For example, to rename the files cited in the first paragraph:

./massren IMG 2008-feb-baseball-
./massren JPG jpeg

The first command replaces “IMG” in every file name to “2008-feb-baseball-“. The second command replaces “JPG” in every file name to “jpeg”. The reason I put “./” at the beginning pf each line is that on my system the working directory is not in the path. So, this addresses the script “massren” in the working directory explicitly…pretty normal in unix shells.

Examining the Code

#!/bin/sh
for filename in *$1*
do
mv -fT “$filename” `echo $filename | sed -e “s/$1/$2/”`
done

This tells your unix shell where to file the program that executes this script. in this case, it is a Bach shell script and the program on my system is called “sh” and is in the “/bin/” directory. This line, in unix jargon is called the shebang line.

This creates a variable called “filename” in a loop (from “do” to “done on the following lines) for each file in the working directory (the current directly) for each file that has the “textfrom” text that you specified. The “$1″ in “*$1*” is a variable that contains the first parameter (like “IMG” in the example). The asterisks surrounding it mean that any file with this text somewhere in the file name will be selected.

The “do” and “done” lines contain the loop. The code between them will be executed for every file matched on the green line.

This line renames each file. In unix, “mv”, the Move command is also used to rename files. The -fT parameters tell mv to go ahead and rename the file and that the file is being renamed and not being moved to another directory. You can see that we are using the $filename variable that was created on the green line – remember that this is a loop and will be run for every file that meets our criteria. “$filename” is enclosed in quotes in case the files being renamed has spaces in the name (in which case, the fromtext parameter would need to be quoted also.

The next part is where the new file name is created using the “sed” command. Note that it is enclosed in “`” characters, called back ticks in unix jargon. Everything enclosed in back ticks is executed and the results of that execution is substituted in the brown command line. So, the current file name (in the $filename variable) is echoed through the sed command. “echo” gets the file name, the “|” (called a pipe in unix jargon) takes that text (the file name) and pipes it into the sed command.

The sed command being used substitutes all of the fromtext (in the $1 variable) with the totext (in the $2 variable). Check out a reference for sed for details. You will see that the “s//” command does a simple substitution of one instance of text with another.

Make your Own Command

Take what you learn here and create your own mass file renaming script! Replace “*$1*” with a globing specification that selects the files you want to process.

Replace the sed command I used here with, for example a tr command. You could use tr to rename file from UPPERCASE to lowercase: tr ‘[A-Z]’ ‘[a-z]’

You can easily debug your new script by inserting echo at the beginning of the brown line to just show the mv command line being created for each file instead of executing it. For example, for the new rename to lower case:

#!/bin/sh
for filename in *
do
echo mv -fT “$filename” `echo $filename | tr ‘[A-Z]’ ‘[a-z]`
done

Note that the selection criteria went from “*$1*” (select files that contain specified text) to “*” (all files in the working directory).

Production Version

#!/bin/sh
#
# massren: Mass file rename utility
#
if [ $# -eq 2 ]
then
    for filename in *$1*
    do
          mv -fT "$filename" `echo $filename | sed -e "s/$1/$2/"`
    done
    exit 0
else
    echo "\nUsage:"
    echo "masren textfrom textto"
    echo "\nWhere:"
    echo "textfrom is the text to replace in each file name."
    echo "textto is the new replacement text.\n"
    exit 1
fi