The Power of the Command Line

The command line separates the amateurs from the experts. The command line lies at the heart of the Unix computing power.

The beauty of command line is that you are able to do relatively complicated tasks in just one line. Take for example renaming of doc files to txt files. An ordinary user will issue the command

bobby-corpuss-imac-5:~ bobby$ mv file1.doc file1.txt

for every file the current directory. If the directory turns out to contain so many files, then the poor user will spend so much time trying to do a non-value added work.

A better use of one’s time is to study how the command line works and be able to do the job in just one line of code:

bobby-corpuss-imac-5:~ bobby$ /bin/ls -1 *.doc |sed 's/(.*).doc/mv & 1.txt/g'|bash

To see how this works, let us dissect the command which is composed of 3 commands linked together using the pipe symbol “|”. The pipe allows you to feed the output of one command to the input stream of the next command. The 3 commands used are:

  • /bin/ls
  • sed
  • bash

The first command will list down the files in the current directory and present them in one column. For example,

bobby-corpuss-imac-5:tmp bobby$ /bin/ls -1 *.doc
file1.doc
file2.doc
file3.doc
file4.doc
file5.doc

The next command is quite tricky so let’s conquer it little by little. The command name is sed which is short for Stream Editor. It takes a regular expression that matches any string ending with a doc. The cryptic looking expression (.*) is nothing to worry about. The “” (backslash) you see that precedes the “(” and “)” is an escape character and is used to indicate to the shell that the next character should not be interpreted. The “.*” is a regular expression composed of “.” and “*”. The “.” tells “sed” to match any character. The “*” modifies the behaviour of “.” by telling “sed” to match a sequence of any character zero or more times. If you remove the escape character, the regular expression reads (.*). The parenthesis tells “sed” that whatever string of characters it matches in .* should be saved for later use. The final part of the regular expression says that the matched expression should contain the string doc.

The last paragraph is really a mouthful. If you are new to this, you might need to read it again, and again. That is just the first part of the “sed” input. Sed commands typically accept inputs of the following format:

sed 's/regex/replacement/g'

where regex is a regular expression to match, as discussed above and replacement is the text which can make use of the saved text matched in the regex. The “g” tells sed to apply the substitution for all matches. Let’s now try to dissect the replacement part of the sed input.

The replacement looks like mv & 1.txt. This still looks complicated but we’re almost done. The symbol & stands for the entire string matching the regular expression. The symbol 1 stands for the sequence of characters that matched (.*). Therefore, an input string file1.doc will give the following values to the replacement:

  • & = file1.doc
  • 1 = file1
  • mv & 1.txt = mv file1.doc file1.txt

If we now try to string the first two commands together, we get:

bobby-corpuss-imac-5:tmp bobby$ /bin/ls -1 *.doc |sed 's/(.*).doc/mv & 1.txt/g'
mv file1.doc file1.txt
mv file2.doc file2.txt
mv file3.doc file3.txt
mv file4.doc file4.txt
mv file5.doc file5.txt

If you look closely at the output above, you can see that we are in effect building a command. For example, the first line says mv file1.doc file1.txt which is a command to move file1.doc to file2.doc. The only thing we need to do now is to execute this command, which is conveniently done by piping the output to bash. Executing this command in the shell gives us the following output.

bobby-corpuss-imac-5:tmp bobby$ ls *.doc
file1.doc	file2.doc	file3.doc	file4.doc	file5.doc
bobby-corpuss-imac-5:tmp bobby$ /bin/ls -1 *.doc |sed 's/(.*).doc/mv & 1.txt/g'|bash
bobby-corpuss-imac-5:tmp bobby$ ls *.docls: *.doc: No such file or directory
bobby-corpuss-imac-5:tmp bobby$ ls *.txt
file1.txt	file2.txt	file3.txt	file4.txt	file5.txt

Are you ready to tap the power of the command line?

Advertisements