shell/Readme.md: Use USERNAME and YYYY-MM-PLACE in git clone instructions
[swc-modular-shell-hearing.git] / shell / Readme.md
1 # The Shell
2
3 **Material by Milad Fatenejad, Sasha Wood, and Radhika Khetani**
4
5 # What is the shell how do I access the shell?
6
7 The *shell* is a program that presents a command line interface
8 which allows you to control your computer using commands entered
9 with a keyboard instead of controlling graphical user interfaces
10 (GUIs) with a mouse/keyboard combination.
11
12 Use a browser to open the tutorial on github, located at:
13     https://github.com/USERNAME/boot-camps/tree/YYYY-MM-PLACE
14
15 Click on the directory named `shell`.
16
17 A *terminal* is a program you run that gives you access to the
18 shell. There are many different terminal programs that vary across
19 operating systems.
20          
21 There are many reasons to learn about the shell. In my opinion, the
22 most important reasons are that: 
23
24 1.  It is very common to encounter the shell and
25     command-line-interfaces in scientific computing, so you will
26     probably have to learn it eventually 
27
28 2.  The shell is a really powerful way of interacting with your
29     computer. GUIs and the shell are complementary - by knowing both
30     you will greatly expand the range of tasks you can accomplish with
31     your computer. You will also be able to perform many tasks more
32     efficiently.
33
34 The shell is just a program and there are many different shell
35 programs that have been developed. The most common shell (and the one
36 we will use) is called the Bourne-Again SHell (bash). Even if bash is
37 not the default shell, it is usually installed on most systems and can be
38 started by typing `bash` in the terminal. Many commands, especially a
39 lot of the basic ones, work across the various shells but many things
40 are different. I recommend sticking with bash and learning it well.
41 ([Here is a link for more information](http://en.wikipedia.org/wiki/Bash_(Unix_shell))
42
43 To open a terminal, just single click on the "Terminal" icon on the
44 Desktop.
45
46 # The Example: Manipulating Experimental Data Files
47
48 We will spend most of our time learning about the basics of the shell
49 by manipulating some experimental data from a hearing test. To get
50 the data for this test, you will need internet access. Just enter the
51 command:
52
53     git clone -b YYYY-MM-PLACE https://github.com/USERNAME/boot-camps.git
54
55 Followed by:
56
57     cd boot-camps
58     git checkout YYYY-MM-PLACE
59
60 These 2 commands will grab all of the data needed for this workshop from the
61 internet.
62
63 # Let's get started
64
65 One very basic command is `echo`. This command just prints text to
66 the terminal. Try the command:
67
68     echo Hello, World
69
70 Then press enter. You should see the text "Hello, World" printed back
71 to you. The echo command is useful for printing from a shell script,
72 for displaying variables, and for generating known values to pass
73 to other programs.
74
75 ## Moving around the file system
76
77 Let's learn how to move around the file system using command line
78 programs. This is really easy to do using a GUI (just click on
79 things). Once you learn the basic commands, you'll see that it is
80 really easy to do in the shell too. 
81
82 First we have to know where we are. The program `pwd` (print working
83 directory) tells you where you are sitting in the directory tree. The
84 command `ls` will list the files in files in the current
85 directory. Directories are often called "folders" because of how they
86 are represented in GUIs. Directories are just listings of files. They
87 can contain other files or directories.
88
89 Whenever you start up a terminal, you will start in a special
90 directory called the *home* directory. Every user has their own home
91 directory where they have full access to do whatever they want. In
92 this case, the `pwd` command tells us that we are in the `/home/swc`
93 directory. This is the home directory for the `swc` user. That is our
94 user name. You can always find out your user name by entering the
95 command `whoami`. 
96
97 **File Types**
98
99 When you enter the `ls` command lists the contents of the current
100 directory. There are several items in the home directory, notice that
101 they are all colored blue. This tells us that all of these items are
102 directories as opposed to files.
103
104 Lets create an empty file using the `touch` command. Enter the
105 command:
106
107     touch testfile
108
109 Then list the contents of the directory again. You should see that a
110 new entry, called `testfile`, exists. It is colored white meaning that
111 it is a file, as opposed to a directory. The `touch` command just
112 creates an empty file. 
113
114 Some terminals will not color the directory entries in this very
115 convenient way. In those terminals, use `ls -F` instead of `ls`. The
116 `-F` argument modifies the results so that a slash is placed at the
117 end of directories. If the file is *executable* meaning that it can be
118 run like a program, then a star fill be placed of the file name.
119
120 You can also use the command `ls -l` to see whether items in a
121 directory are files or directories. `ls -l` gives a lot more
122 information too, such as the size of the file and information about
123 the owner. If the entry is a directory, then the first letter will be
124 a "d". The fifth column shows you the size of the entries in
125 bytes. Notice that `testfile` has a size of zero.
126
127 Now, let's get rid of `testfile`. To remove a file, just enter the
128 command:
129
130     rm testfile
131
132 The `rm` command can be used to remove files. If you enter `ls` again,
133 you will see that `testfile` is gone.
134
135
136 **Changing Directories**
137
138 Now, let's move to a different directory. The command `cd` (change
139 directory) is used to move around. Let's move into the `boot-camps`
140 directory. Enter the following command:
141
142     cd boot-camps
143
144 Now use the `ls` command to see what is inside this directory. You
145 will see that there is an entry which is green. This means that this
146 is an executable. If you use `ls -F` you will see that this file ends
147 with a star.
148
149 This directory contains all of the material for this boot camp. Now
150 move to the directory containing the data for the shell tutorial:
151
152     cd shell
153
154 If you enter the `cd` command by itself, you will return to the home
155 directory. Try this, and then navigate back to the `shell`
156 directory.
157
158 ## Arguments
159
160 Most programs take additional arguments that control their exact
161 behavior. For example, `-F` and `-l` are arguments to `ls`.  The `ls`
162 program, like many programs, take a lot of arguments. But how do we
163 know what the options are to particular commands?
164
165 Most commonly used shell programs have a manual. You can access the
166 manual using the `man` program. Try entering:
167
168     man ls
169
170 This will open the manual page for `ls`. Use the space key to go
171 forward and b to go backwards. When you are done reading, just hit `q`
172 to exit.
173
174 Programs that are run from the shell can get extremely complicated. To
175 see an example, open up the manual page for the `find` program,
176 which we will use later this session. No one can possibly learn all of
177 these arguments, of course. So you will probably find yourself
178 referring back to the manual page frequently.
179
180 **Examining the contents of other directories**
181
182 By default, the `ls` commands lists the contents of the working
183 directory (i.e. the directory you are in). You can always find the
184 directory you are in using the `pwd` command. However, you can also
185 give `ls` the names of other directories to view. Navigate to the
186 home directory if you are not already there. Then enter the
187 command:
188
189     ls boot-camps
190
191 This will list the contents of the `boot-camps` directory without
192 you having to navigate there. Now enter:
193
194     ls boot-camps/shell
195
196 This prints the contents of `shell`. The `cd` command works in a
197 similar way. Try entering:
198
199     cd boot-camps/shell
200
201 and you will jump directly to `shell` without having to go through
202 the intermediate directory.
203
204 ## Full vs. Relative Paths
205
206 The `cd` command takes an argument which is the directory
207 name. Directories can be specified using either a *relative* path a
208 full *path*. The directories on the computer are arranged into a
209 hierarchy. The full path tells you where a directory is in that
210 hierarchy. Navigate to the home directory. Now, enter the `pwd`
211 command and you should see:
212
213     /home/swc
214
215 which is the full name of your home directory. This tells you that you
216 are in a directory called `swc`, which sits inside a directory called
217 `home` which sits inside the very top directory in the hierarchy. The
218 very top of the hierarchy is a directory called `/` which is usually
219 referred to as the *root directory*. So, to summarize: `swc` is a
220 directory in `home` which is a directory in `/`.
221
222 Now enter the following command:
223
224     cd /home/swc/boot-camps/shell
225
226 This jumps to `shell`. Now go back to the home directory. We saw
227 earlier that the command:
228
229     cd boot-camps/shell
230
231 had the same effect - it took us to the `shell` directory. But,
232 instead of specifying the full path
233 (`/home/swc/boot-camps/shell`), we specified a *relative path*. In
234 other words, we specified the path relative to our current
235 directory. A full path always starts with a `/`. A relative path does
236 not. You can usually use either a full path or a relative path
237 depending on what is most convenient. If we are in the home directory,
238 it is more convenient to just enter the relative path since it
239 involves less typing.
240
241 Now, list the contents of the /bin directory. Do you see anything
242 familiar in there?
243
244
245 ## Saving time with shortcuts, wild cards, and tab completion
246
247 **Shortcuts**
248
249 There are some shortcuts which you should know about. Dealing with the
250 home directory is very common. So, in the shell the tilde character,
251 `~`, is a shortcut for your home directory. Navigate to the `shell`
252 directory, then enter the command:
253
254     ls ~
255
256 This prints the contents of your home directory, without you having to
257 type the full path. The shortcut `..` always refers to the directory
258 above your current directory. Thus: 
259
260     ls ..
261
262 prints the contents of the `/home/swc/boot-camps`. You can chain
263 these together, so:
264
265     ls ../../
266
267 prints the contents of `/home/swsc` which is your home
268 directory. Finally, the special directory `.` always refers to your
269 current directory. So, `ls`, `ls .`, and `ls ././././.` all do the
270 same thing, they print the contents of the current directory. This may
271 seem like a useless shortcut right now, but we'll see when it is
272 needed in a little while.
273
274 To summarize, the commands `ls ~`, `ls ~/.`, `ls ../../`, and `ls
275 /home/swc` all do exactly the same thing. These shortcuts are not
276 necessary, they are provided for your convenience.
277
278 **Our data set: Cochlear Implants**
279
280 A cochlear implant is a small electronic device that is surgically
281 implanted in the inner ear to give deaf people a sense of
282 hearing. More than a quarter of a million people have them, but there
283 is still no widely-accepted benchmark to measure their effectiveness.
284 In order to establish a baseline for such a benchmark, our supervisor
285 got teenagers with CIs to listen to audio files on their computer and
286 report:
287
288 1.  the quietest sound they could hear
289 2.  the lowest and highest tones they could hear
290 3.  the narrowest range of frequencies they could discriminate
291
292 To participate, subjects attended our laboratory and one of our lab
293 techs played an audio sample, and recorded their data - when they
294 first heard the sound, or first heard a difference in the sound.  Each
295 set of test results were written out to a text file, one set per file.
296 Each participant has a unique subject ID, and a made-up subject name.
297 Each experiment has a unique experiment ID. The experiment has
298 collected 351 files so far.
299
300 The data is a bit of a mess! There are inconsistent file names, there
301 are extraneous "NOTES" files that we'd like to get rid of, and the
302 data is spread across many directories. We are going to use shell
303 commands to get this data into shape. By the end we would like to:
304
305 1.  Put all of the data into one directory called "alldata"
306
307 2.  Have all of the data files in there, and ensure that every file
308     has a ".txt" extension
309
310 3.  Get rid of the extraneous "NOTES" files
311
312 If we can get through this example in the available time, we will move
313 onto more advanced shell topics...
314
315 **Wild cards**
316
317 Navigate to the `~/boot-camps/shell/data/THOMAS` directory. This
318 directory contains our hearing test data for THOMAS. If we type `ls`,
319 we will see that there are a bunch of files which are just four digit
320 numbers. By default, `ls` lists all of the files in a given
321 directory. The `*` character is a shortcut for "everything". Thus, if
322 you enter `ls *`, you will see all of the contents of a given
323 directory. Now try this command:
324
325     ls *1
326
327 This lists every file that ends with a `1`. This command:
328
329     ls /usr/bin/*.sh
330
331 Lists every file in `/usr/bin` that ends in the characters `.sh`. And
332 this command:
333
334     ls *4*1
335
336 lists every file in the current directory which contains the number
337 `4`, and ends with the number `1`. There are four such files: `0241`,
338 `0341`, `0431`, and `0481`. 
339
340 So how does this actually work? Well...when the shell (bash) sees a
341 word that contains the `*` character, it automatically looks for files
342 that match the given pattern. In this case, it identified four such
343 files. Then, it replaced the `*4*1` with the list of files, separated
344 by spaces. In other the two commands:
345
346     ls *4*1
347     ls 0241 0341 0431 0481
348
349 are exactly identical. The `ls` command cannot tell the difference
350 between these two things.
351
352 * * * *
353 **Short Exercise**
354
355 Do each of the following using a single `ls` command without
356 navigating to a different directory.
357
358 1.  List all of the files in `/bin` that contain the letter `a`
359 2.  List all of the files in `/bin` that contain the letter `a` or the letter `b`
360 3.  List all of the files in `/bin` that contain the letter `a` AND the letter `b`
361
362 * * * *
363
364 **Tab Completion**
365
366 Navigate to the home directory. Typing out directory names can waste a
367 lot of time. When you start typing out the name of a directory, then
368 hit the tab key, the shell will try to fill in the rest of the
369 directory name. For example, enter:
370
371     cd S<tab>
372
373 The shell will fill in the rest of the directory name for
374 `boot-camps`. Now enter:
375
376     ls 3<tab><tab>
377
378 When you hit the first tab, nothing happens. The reason is that there
379 are multiple directories in the home directory which start with
380 3. Thus, the shell does not know which one to fill in. When you hit
381 tab again, the shell will list the possible choices. 
382
383 Tab completion can also fill in the names of programs. For example,
384 enter `e<tab><tab>`. You will see the name of every program that
385 starts with an `e`. One of those is `echo`. If you enter `ec<tab>` you
386 will see that tab completion works.
387
388 **Command History**
389
390 You can easily access previous commands.  Hit the up arrow.  
391 Hit it again.  You can step backwards through your command history. 
392 The down arrow takes your forwards in the command history.  
393
394 ^-C will cancel the command you are writing, and give you a fresh prompt.
395
396 ^-R will do a reverse-search through your command history.  This
397 is very useful.
398
399 ## Which program? ##
400
401 Commands like `ls`, `rm`, `echo`, and `cd` are just ordinary programs
402 on the computer. A program is just a file that you can *execute*. The
403 program `which` tells you the location of a particular program. For
404 example:
405
406     which ls
407
408 Will return "/bin/ls". Thus, we can see that `ls` is a program that
409 sits inside of the `/bin` directory. Now enter:
410
411     which find
412
413 You will see that `find` is a program that sits inside of the
414 `/usr/bin` directory.
415
416 So ... when we enter a program name, like `ls`, and hit enter, how
417 does the shell know where to look for that program? How does it know
418 to run `/bin/ls` when we enter `ls`. The answer is that when we enter
419 a program name and hit enter, there are a few standard places that the
420 shell automatically looks. If it can't find the program in any of
421 those places, it will print an error saying "command not found". Enter
422 the command:
423
424     echo $PATH
425
426 This will print out the value of the `PATH` environment variable. More
427 on environment variables later. Notice that a list of directories,
428 separated by colon characters, is listed. These are the places the
429 shell looks for programs to run. If your program is not in this list,
430 then an error is printed. The shell ONLY checks in the places listed
431 in the `PATH` environment variable. 
432
433 Navigate to the `shell` directory and list the contents. You will
434 notice that there is a program (executable file) called `hello` in
435 this directory. Now, try to run the program by entering:
436
437     hello
438
439 You should get an error saying that hello cannot be found. That is
440 because the directory `/home/swc/boot-camps/shell` is not in the
441 `PATH`. You can run the `hello` program by entering:
442
443     ./hello
444
445 Remember that `.` is a shortcut for the current working
446 directory. This tells the shell to run the `hello` program which is
447 located right here. So, you can run any program by entering the path
448 to that program. You can run `hello` equally well by specifying:
449
450     /home/swc/boot-camps/shell/hello
451
452 Or by entering:
453
454     ../shell/hello
455
456 When there are no `/` characters, the shell assumes you want to look
457 in one of the default places for the program.
458
459
460 ## Examining Files
461
462 We now know how to switch directories, run programs, and look at the
463 contents of directories, but how do we look at the contents of files?
464
465 The easiest way to examine a file is to just print out all of the
466 contents using the program `cat`. Enter the following command:
467
468     cat ex_data.txt
469
470 This prints out the contents of the `ex_data.txt` file. If you enter:
471
472     cat ex_data.txt ex_data.txt
473
474 It will print out the contents of `ex_data.txt` twice. `cat` just
475 takes a list of file names and writes them out one after another (this
476 is where the name comes from, `cat` is short for concatenate). 
477
478 * * * *
479 **Short Exercises**
480
481 1.  Print out the contents of the `~/boot-camps/shell/dictionary.txt`
482     file. What does this file contain?
483
484 2.  Without changing directories, (you should still be in `shell`),
485     use one short command to print the contents of all of the files in
486     the `/home/swc/boot-camps/shell/data/THOMAS` directory.
487
488 * * * *
489
490 `cat` is a terrific program, but when the file is really big, it can
491 be annoying to use. The program, `less`, is useful for this
492 case. Enter the following command:
493
494     less ~/boot-camps/shell/dictionary.txt
495
496 `less` opens the file, and lets you navigate through it. The commands
497 are identical to the `man` program. Use "space" to go forward and hit
498 the "b" key to go backwards. The "g" key goes to the beginning of the
499 file and "G" goes to the end. Finally, hit "q" to quit.
500
501 `less` also gives you a way of searching through files. Just hit the
502 "/" key to begin a search. Enter the name of the word you would like
503 to search for and hit enter. It will jump to the next location where
504 that word is found. Try searching the `dictionary.txt` file for the
505 word "cat". If you hit "/" then "enter", `less` will just repeat
506 the previous search. `less` searches from the current location and
507 works its way forward. If you are at the end of the file and search
508 for the word "cat", `less` will not find it. You need to go to the
509 beginning of the file and search.
510
511 Remember, the `man` program uses the same commands, so you can search
512 documentation using "/" as well!
513
514 * * * *
515 **Short Exercise**
516
517 Use the commands we've learned so far to figure out how to search
518 in reverse while using `less`.
519
520 * * * * 
521
522
523 ## Redirection
524
525 Let's turn to the experimental data from the hearing tests that we
526 began with. This data is located in the `~/boot-camps/shell/data`
527 directory. Each subdirectory corresponds to a particular participant
528 in the study. Navigate to the `Bert` subdirectory in `data`.  There
529 are a bunch of text files which contain experimental data
530 results. Lets print them all:
531
532     cat au*
533
534 Now enter the following command:
535
536     cat au* > ../all_data
537
538 This tells the shell to take the output from the `cat au*` command and
539 dump it into a new file called `../all_data`. To verify that this
540 worked, examine the `all_data` file. If `all_data` had already
541 existed, we would overwritten it. So the `>` character tells the shell
542 to take the output from what ever is on the left and dump it into the
543 file on the right. The `>>` characters do almost the same thing,
544 except that they will append the output to the file if it already
545 exists.
546
547 * * * *
548 **Short Exercise**
549
550 Use `>>`, to append the contents of all of the files which contain the
551 number 4 in the directory:
552
553     /home/swc/boot-camps/shell/data/gerdal
554
555 to the existing `all_data` file. Thus, when you are done `all_data`
556 should contain all of the experiment data from Bert and any
557 experimental data file from gerdal that contains the number 4.
558
559 * * * *
560
561
562 ## Creating, moving, copying, and removing
563
564 We've created a file called `all_data` using the redirection operator
565 `>`. This is critical file so we have to make copies so that the data
566 is backed up. Lets copy the file using the `cp` command. The `cp`
567 command backs up the file. Navigate to the `data` directory and enter:
568
569     cp all_data all_data_backup
570
571 Now `all_data_backup` has been created as a copy of `all_data`. We can
572 move files around using the command `mv`. Enter this command:
573
574     mv all_data_backup /tmp/
575
576 This moves `all_data_backup` into the directory `/tmp`. The directory
577 `/tmp` is a special directory that all users can write to. It is a
578 temporary place for storing files. Data stored in `/tmp` is
579 automatically deleted when the computer shuts down.
580
581 The `mv` command is also how you rename files. Since this file is so
582 important, let's rename it:
583
584     mv all_data all_data_IMPORTANT
585
586 Now the file name has been changed to all_data_IMPORTANT. Let's delete
587 the backup file now:
588
589     rm /tmp/all_data_backup
590
591 The `mkdir` command is used to create a directory. Just enter `mkdir`
592 followed by a space, then the directory name. 
593
594 * * * *
595 **Short Exercise**
596
597 Do the following:
598
599 1.  Rename the `all_data_IMPORTANT` file to `all_data`.
600 2.  Create a directory in the `data` directory called `foo`
601 3.  Then, copy the `all_data` file into `foo`
602
603 * * * *
604
605 By default, `rm`, will NOT delete directories. You can tell `rm` to
606 delete a directory using the `-r` option. Enter the following command:
607
608     rm -r foo
609
610
611 ## Count the words
612
613 The `wc` program (word count) counts the number of lines, words, and
614 characters in one or more files. Make sure you are in the `data`
615 directory, then enter the following command:
616
617     wc Bert/* gerdal/*4*
618
619 For each of the files indicated, `wc` has printed a line with three
620 numbers. The first is the number of lines in that file. The second is
621 the number of words. Finally, the total number of characters is
622 indicated. The final line contains this information summed over all of
623 the files. Thus, there were 10445 characters in total. 
624
625 Remember that the `Bert/*` and `gerdal/*4*` files were merged
626 into the `all_data` file. So, we should see that `all_data` contains
627 the same number of characters:
628
629     wc all_data
630
631 Every character in the file takes up one byte of disk space. Thus, the
632 size of the file in bytes should also be 10445. Let's confirm this:
633
634     ls -l all_data
635
636 Remember that `ls -l` prints out detailed information about a file and
637 that the fifth column is the size of the file in bytes.
638
639 * * * *
640 **Short Exercise**
641
642 Figure out how to get `wc` to print the length of the longest line in
643 `all_data`.
644
645 * * * *
646
647 ## The awesome power of the Pipe
648
649 Suppose I wanted to only see the total number of character, words, and
650 lines across the files `Bert/*` and `gerdal/*4*`. I don't want to
651 see the individual counts, just the total. Of course, I could just do:
652
653     wc all_data
654
655 Since this file is a concatenation of the smaller files. Sure, this
656 works, but I had to create the `all_data` file to do this. Thus, I
657 have wasted a precious 7062 bytes of hard disk space. We can do this
658 *without* creating a temporary file, but first I have to show you two
659 more commands: `head` and `tail`. These commands print the first few,
660 or last few, lines of a file, respectively. Try them out on
661 `all_data`:
662
663     head all_data
664     tail all_data
665
666 The `-n` option to either of these commands can be used to print the
667 first or last `n` lines of a file. To print the first/last line of the
668 file use:
669
670     head -n 1 all_data
671     tail -n 1 all_data
672
673 Let's turn back to the problem of printing only the total number of
674 lines in a set of files without creating any temporary files. To do
675 this, we want to tell the shell to take the output of the `wc Bert/*
676 gerdal/*4*` and send it into the `tail -n 1` command. The `|`
677 character (called pipe) is used for this purpose. Enter the following
678 command:
679
680     wc Bert/* gerdal/Data0559 | tail -n 1
681
682 This will print only the total number of lines, characters, and words
683 across all of these files. What is happening here? Well, `tail`, like
684 many command line programs will read from the *standard input* when it
685 is not given any files to operate on. In this case, it will just sit
686 there waiting for input. That input can come from the user's keyboard
687 *or from another program*. Try this:
688
689     tail -n 2
690
691 Notice that your cursor just sits there blinking. Tail is waiting for
692 data to come in. Now type:
693
694     French
695     fries
696     are
697     good
698
699 then CONTROL+d. You should is the lines:
700
701     are
702     good
703
704 printed back at you. The CONTROL+d keyboard shortcut inserts an
705 *end-of-file* character. It is sort of the standard way of telling the
706 program "I'm done entering data". The `|` character is replaces the
707 data from the keyboard with data from another command. You can string
708 all sorts of commands together using the pipe. 
709
710 The philosophy behind these command line programs is that none of them
711 really do anything all that impressive. BUT when you start chaining
712 them together, you can do some really powerful things really
713 efficiently. If you want to be proficient at using the shell, you must
714 learn to become proficient with the pipe and redirection operators:
715 `|`, `>`, `>>`.
716
717
718 **A sorting example**
719
720 Let's create a file with some words to sort for the next example. We
721 want to create a file which contains the following names:
722
723     Bob
724     Alice
725     Diane
726     Charles
727
728 To do this, we need a program which allows us to create text
729 files. There are many such programs, the easiest one which is
730 installed on almost all systems is called `nano`. Navigate to `/tmp`
731 and enter the following command:
732
733     nano toBeSorted
734
735 Now enter the four names as shown above. When you are done, press
736 CONTROL+O to write out the file. Press enter to use the file name
737 `toBeSorted`. Then press CONTROL+x to exit `nano`.
738
739 When you are back to the command line, enter the command:
740
741     sort toBeSorted
742
743 Notice that the names are now printed in alphabetical order.
744
745 * * * *
746 **Short Exercise**
747
748 Use the `echo` command and the append operator, `>>`, to append your
749 name to the file, then sort it and make a new file called Sorted.
750
751 * * * *
752
753 Let's navigate back to `~/boot-camps/shell/data`. Enter the following command:
754
755     wc Bert/* | sort -k 3 -n
756
757 We are already familiar with what the first of these two commands
758 does: it creates a list containing the number of characters, words,
759 and lines in each file in the `Bert` directory. This list is then
760 piped into the `sort` command, so that it can be sorted. Notice there
761 are two options given to sort:
762
763 1.  `-k 3`: Sort based on the third column
764 2.  `-n`: Sort in numerical order as opposed to alphabetical order
765
766 Notice that the files are sorted by the number of characters.
767
768 * * * *
769 **Short Exercise**
770
771 Use the `man` command to find out how to sort the output from `wc` in
772 reverse order.
773
774 * * * *
775
776 * * * * 
777 **Short Exercise**
778
779 Combine the `wc`, `sort`, `head` and `tail` commands so that only the
780 `wc` information for the largest file is listed
781
782 Hint: To print the smallest file, use:
783
784     wc Bert/* | sort -k 3 -n | head -n 1
785
786 * * * * 
787
788 Printing the smallest file seems pretty useful. We don't want to type
789 out that long command often. Let's create a simple script, a simple
790 program, to run this command. The program will look at all of the
791 files in the current directory and print the information about the
792 smallest one. Let's call the script `smallest`. We'll use `nano` to
793 create this file. Navigate to the `data` directory, then:
794
795     nano smallest
796
797 Then enter the following text:
798
799     #!/bin/bash
800     wc * | sort -k 3 -n | head -n 1
801
802 Now, `cd` into the `Bert` directory and enter the command
803 `../smallest`. Notice that it says permission denied. This happens
804 because we haven't told the shell that this is an executable
805 file. If you do `ls -l ../smallest`, it will show you the permissions on 
806 the left of the listing.
807
808 Enter the following commands:
809
810     chmod a+x ../smallest
811     ../smallest
812
813 The `chmod` command is used to modify the permissions of a file. This
814 particular command modifies the file `../smallest` by giving all users
815 (notice the `a`) permission to execute (notice the `x`) the file. If
816 you enter:
817
818     ls -l ../smallest
819
820 You will see that the file name is green and the permissions have changed. 
821 Congratulations, you just created your first shell script!
822
823 # Searching files
824
825 You can search the contents of a file using the command `grep`. The
826 `grep` program is very powerful and useful especially when combined
827 with other commands by using the pipe. Navigate to the `Bert`
828 directory. Every data file in this directory has a line which says
829 "Range". The range represents the smallest frequency range that can be
830 discriminated. Lets list all of the ranges from the tests that Bert
831 conducted:
832
833     grep Range *
834
835 * * * * 
836 **Short Exercise**
837
838 Create an executable script called `smallestrange` in the `data`
839 directory, that is similar to the `smallest` script, but prints the
840 file containing the file with the smallest Range. Use the commands
841 `grep`, `sort`, and `tail` to do this.
842
843 * * * * 
844
845
846 # Finding files
847
848 The `find` program can be used to find files based on arbitrary
849 criteria. Navigate to the `data` directory and enter the following
850 command:
851
852     find . -print
853
854 This prints the name of every file or directory, recursively, starting
855 from the current directory. Let's exclude all of the directories:
856
857     find . -type f -print
858
859 This tells `find` to locate only files. Now try these commands:
860
861     find . -type f -name "*1*"
862     find . -type f -name "*1*" -or -name "*2*" -print
863     find . -type f -name "*1*" -and -name "*2*" -print
864
865 The `find` command can acquire a list of files and perform some
866 operation on each file. Try this command out:
867
868     find . -type f -exec grep Volume {} \;
869
870 This command finds every file starting from `.`. Then it searches each
871 file for a line which contains the word "Volume". The `{}` refers to
872 the name of each file. The trailing `\;` is used to terminate the
873 command.  This command is slow, because it is calling a new instance
874 of `grep` for each item the `find` returns.
875
876 A faster way to do this is to use the `xargs` command:
877
878     find . -type f -print | xargs grep Volume
879
880 `find` generates a list of all the files we are interested in, 
881 then we pipe them to `xargs`.  `xargs` takes the items given to it 
882 and passes them as arguments to `grep`.  `xargs` generally only creates
883 a single instance of `grep` (or whatever program it is running).
884
885 * * * * 
886 **Short Exercise**
887
888 Navigate to the `data` directory. Use one find command to perform each
889 of the operations listed below (except number 2, which does not
890 require a find command):
891
892 1.  Find any file whose name is "NOTES" within `data` and delete it 
893
894 2.  Create a new directory called `cleaneddata`
895
896 3.  Move all of the files within `data` to the `cleaneddata` directory
897
898 4.  Rename all of the files to ensure that they end in `.txt` (note:
899     it is ok for the file name to end in `.txt.txt`
900
901 Hint: If you make a mistake and need to start over just do the
902 following:
903
904 1.  Navigate to the `shell` directory
905
906 2.  Delete the `data` directory
907
908 3.  Enter the command: `git checkout -- data` You should see that the
909     data directory has reappeared in its original state
910
911 **BONUS**
912
913 Redo exercise 4, except rename only the files which do not already end
914 in `.txt`. You will have to use the `man` command to figure out how to
915 search for files which do not match a certain name. 
916
917 * * * * 
918
919
920
921 ## Bonus:
922
923 **backtick, xargs**: Example find all files with certain text
924
925 **alias** -> rm -i
926
927 **variables** -> use a path example
928
929 **.bashrc**
930
931 **du**
932
933 **ln**
934
935 **ssh and scp**
936
937 **Regular Expressions**
938
939 **Permissions**
940
941 **Chaining commands together**