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 = file1mv & \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?