who | sed 's/ .*//' - delete everything after the first space - By default sed command executes the command for every line - You can specify a range before specifying the command - The command will be executed only for those lines mentioned in the range Ranges can be line numbers such as 12,17 - Ranges can be patterns as well such as /^$/ or /^$/! First means all the blank lines Second means all the non-blank lines - Mix line numbers with pattern sed '1,/^$/d' Delete from line 1 upto first occurrence of a blank line sed '/^$/,/^end/p' Print group of lines strating from a blank line going to a line which starts with the string end. $ who | sed '/lingras/p' lingras pts/1 Feb 14 19:16 lingras pts/1 Feb 14 19:16 stevenso pts/8 Feb 14 18:52 avstud pts/6 Feb 14 18:16 phone pts/38 Feb 13 23:32 newbiggi pts/59 Feb 14 15:38 peltsch pts/60 Feb 14 11:34 lingras pts/46 Feb 14 10:23 lingras pts/46 Feb 14 10:23 lingras pts/49 Feb 14 10:23 lingras pts/49 Feb 14 10:23 $ who | sed '/lingras/' UX:sed: ERROR: Unrecognized command: /lingras/ $ who | sed -n '/lingras/p' lingras pts/1 Feb 14 19:16 lingras pts/46 Feb 14 10:23 lingras pts/49 Feb 14 10:23 $ who | sed -n '/lingras/!p' stevenso pts/8 Feb 14 18:52 avstud pts/6 Feb 14 18:16 phone pts/38 Feb 13 23:32 newbiggi pts/59 Feb 14 15:38 peltsch pts/60 Feb 14 11:34 $ - We can emulate greps using sed - Even though we have been using single line programs typed directly on the command line, sed can accept a program from a file. The option is -f sed -f program-file input-file Awk - awk programs have the following format pattern{action} $ who | awk '$1=="lingras" {print $1}' lingras lingras lingras $ - awk program has a lot of special variables - NR means line number $ who | awk '$1=="lingras" {print NR, $1}' 1 lingras 7 lingras 8 lingras $ - lingras occurred at line number 1,7 and 8 - $1 corresponds to first field, $2 corresponds second field $0 corresponds to entire line $ who | awk -F: '{print $1}' lingras pts/1 Feb 14 19 stevenso pts/8 Feb 14 18 avstud pts/6 Feb 14 18 phone pts/38 Feb 13 23 newbiggi pts/59 Feb 14 15 peltsch pts/60 Feb 14 11 lingras pts/46 Feb 14 10 lingras pts/49 Feb 14 10 $ who lingras pts/1 Feb 14 19:16 stevenso pts/8 Feb 14 18:52 avstud pts/6 Feb 14 18:16 phone pts/38 Feb 13 23:32 newbiggi pts/59 Feb 14 15:38 peltsch pts/60 Feb 14 11:34 lingras pts/46 Feb 14 10:23 lingras pts/49 Feb 14 10:23 $ who | awk -F: '{print NF,$1}' 2 lingras pts/1 Feb 14 19 2 stevenso pts/8 Feb 14 18 2 avstud pts/6 Feb 14 18 2 phone pts/38 Feb 13 23 2 newbiggi pts/59 Feb 14 15 2 peltsch pts/60 Feb 14 11 2 lingras pts/46 Feb 14 10 2 lingras pts/49 Feb 14 10 $ - We can specify a different field separator by using -F option Previous command uses : as the field separator that's why we have NF giving us a value of 2 - NF corresponds to number of fields on the line - $NF will ofcourse correspond to the last field $ who | awk '$1=="lingras" {print NR, NF, $NF}' 1 5 19:16 7 5 10:23 8 5 10:23 $ $ last -10 | egrep '\(' | awk '{print $NF}' | sed 's/(//' | sed 's/)//'\ > | awk -F: '{print $1,$2}' 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 $ - The store the output from last command in a file called say __temp__ - run the previous series of commands by greping the file __temp__ for tty to get the modem statistics for pts to get the campus statistics $ egrep "tty" __temp__ $ egrep "pts" __temp__ - awk allows two special patterns called BEGIN and END egrep tty __temp__ | egrep '\(' | awk '{print $NF}'\ | sed 's/(//' | sed 's/)//'\ | awk -F: '{print $1,$2}' | awk -f count.awk count.awk BEGIN{logins=0;time=0;max=0} { logins = logins+1; time = time+60*$1+$2; if(max < (60*$1+$2)) max = 60*$1+$2; } END{ hours=(time/logins)/60; minutes=(time/logins)%60; mhours=max/60; mminutes=max%60; printf("Campus\t%d:%d\t%d:%d\n",hours,minutes,mhours,mminutes); } $ schedule | awk '$1=="95W2"{printf("%s%s\n",$2,$3)}' | tr '[A-Z]' '[a-z]'