% $Id: tools_basic.tex,v 1.1 2003/11/27 02:44:21 nicku Exp nicku $
\chapter{Basic Tools}
\label{cha:basic-tools}
{\mns



\subsection{Objectives}
\label{sec:basic-linux-unix-tools-objectives}

At the end of this section, you will be able to:
\begin{itemize}
  \item Use the most frequently used Linux tools to:
  \begin{itemize}
    \item Find files
    \item Get information about commands
    \item View file contents
    \item Get information about files
    \item Operate on file contents
    \item Do simple text manipulation
    \item Schedule jobs
  \end{itemize}
  \item Combine tools to solve problems
  \item Understand and use the Linux printing subsystem
\end{itemize}


\section{Introduction}
\label{sec:basic-linux-unix-tools-intro}

The basic Linux command-line utilities dealt with here, are:
 
\renewcommand*{\bottomfraction}{.6} % default is 0.3
\renewcommand*{\topfraction}{.9} % default is 0.7
\renewcommand*{\textfraction}{0.05} % default is 0.2

\begin{table}[h]%
  \begin{center}%
{\myss
\medskip

%%\setlength{\extrarowheight}{1pt}
%% \begin{tabular}[t]{|l|l|}   \hline
%% Finding files                       &  {\pgn find}    \\
%%                                     &  {\pgn locate}    \\  \hline
%% Getting info  about commands        &  {\pgn man}    \\  \hline
%% Viewing file contents               &  {\pgn cat}    \\
%%                                     &  {\pgn less}    \\
                                   
%%  &  {\pgn head}/{\pgn tail}    \\  \hline
%% Getting information about a file    &  {\pgn ls}    \\
%%                                     &  {\pgn file}    \\
%%                                     &  {\pgn wc}    \\
%%                                     &  {\pgn diff}    \\
%%                                     &  {\pgn cmp}    \\  \hline
%% Operating on file contents          &  {\pgn grep}    \\
%%                                     &  {\pgn sort}   \\
%%                                     &  {\pgn uniq}    \\
%%                                     &  {\pgn split}/{\pgn csplit} \\
%%                                     &  {\pgn cut}    \\
%%                                     &  {\pgn paste}    \\
%%                                     &  {\pgn tar}    \\
%%                                     &  {\pgn gzip}/{\pgn bzip2}   \\  \hline
%% Simple text manipulation            &  {\pgn tr}    \\
%%                                     &  {\pgn expr}    \\  \hline
%% Scheduling jobs                     &  {\pgn at}   \\
%%                                     &  {\pgn crontab}     \\  \hline
%%\end{tabular}
\setlength{\extrarowheight}{0pt}%
\begin{tabular}[t]{l>{\pgn}l} \toprule
Finding files:                      &  {\pgn find}    \\
                                    &  {\pgn locate}    \\  \midrule
Getting info  about commands:       &  {\pgn man}    \\  \midrule
Viewing file contents:              &  {\pgn cat}    \\
                                    &  {\pgn less}    \\
                                   
 &  {\pgn head}/{\pgn tail}    \\  \midrule
Getting information about a file:   &  {\pgn ls}    \\
                                    &  {\pgn file}    \\
                                    &  {\pgn wc}    \\
                                    &  {\pgn diff}    \\
                                    &  {\pgn cmp}    \\  \midrule
Operating on file contents:         &  {\pgn grep}    \\
                                    &  {\pgn sort}   \\
                                    &  {\pgn uniq}    \\
                                    &  {\pgn split}/{\pgn csplit} \\
                                    &  {\pgn cut}    \\
                                    &  {\pgn paste}    \\
                                    &  {\pgn tar}    \\
                                    &  {\pgn gzip}/{\pgn bzip2}   \\  \midrule
Simple text manipulation:           &  {\pgn tr}    \\
                                    &  {\pgn expr}    \\  \midrule
Scheduling jobs:                    &  {\pgn at}   \\
                                    &  {\pgn crontab} \\ \bottomrule
\end{tabular}
}
    \caption{Basic Linux utilities}
    \label{tab:basic-linux-utilities}
  \end{center}
\end{table}
  


\section{Using Tools}
\label{sec:basic-linux-unix-tools-using-tools}


\begin{itemize}
\item Typical Linux systems contain over 1000 command-line tools
\item Tools are combined (via pipes and redirection) to solve specific problems
\item Most tools have a standard syntax:

\begin{quote}
{\cmdn \$ command [{\usb options}] [{\usb files ... }]}
\end{quote}
  
\item Some arguments must be quoted
\item Standard input often read if no filename given
\item Most tools can take several filename arguments 
\item Desktop/windowing environments may provide graphical wrappers to some tools
\item Serious Linux administrators and users know the key command-lines well
\item The terms `command' and `tool' are used interchangeably here
\end{itemize}





\section{The On-Line Manual ({\pgn man})}
\label{sec:basic-linux-unix-tools-basic-man}


\begin{itemize}
  
\item Most commands have an associated man page
\item Accessed by typing:
  
  {\cmdn \$ man {\usb command}[s]}


\item Brings up a page of information usually detailing:
  \begin{itemize}
  \item command name, section number, description
  \item syntax
  \item options
  \item version information
  \item location of configuration files
  \item other related commands
  \item examples of usage
  \item known bugs (if any \ldots)
  \end{itemize}


\end{itemize}



\section{Finding Files the Long Way ({\pgn find})}
\label{sec:basic-linux-unix-tools-find}

%IMPROVEME: This foil on find needs to be split up into two or more clearer foils, it's too icky at the moment (LW)

\begin{itemize}
\item {\pgn find} searches the filesystem in real time;
   \begin{itemize}
    \item Makes disks work hard
   \end{itemize}

\item Can find files by name, type, size, dates, e.g
  \begin{itemize}
    \item To find all files ending with {\fn .jpg} under the current
      directory:\\
    {\cmdn find . -name "*.jpg"}
    \item To find all filenames ending in {\fn .jpg} {\em and} modified in
    the last 8 days below {\fn /etc}\\
    {\cmdn find /etc -name "*.jpg" -mtime -8}
  \end{itemize}
  \item Tests can be combined with {\cmdn -o} and negated with {\kbk !}, for example:
  \begin{itemize}
    \item To find all filenames {\em not} ending in {\fn .jpg} {\em
          or} files which were modified in the last 8 days under {\fn /etc}\\
    {\cmdn find /etc \bs! -name "*.jpg" -o -mtime -8}
  \end{itemize}
  \item Can execute commands on the files it finds.  The name of the
        file found is placed in \{\}~\footnote{This is not a resource friendly way of doing things. {\cmdn xargs} may be better}
\begin{verbatim}
find . -name "*.gif" -exec ls -l {} \;
\end{verbatim}
\end{itemize}

\providecommand*{\bsn}{\texttt{\char '134}}

\section{Find examples}
\label{sec:find-examples}

\begin{itemize}
\item First, an example which is wrong:
\begin{alltt}
$ \textbf{find /usr/bin/c*} # WRONG!
\end{alltt}%$
This is \emph{wrong} because the shell expands the \texttt{c*} to all
the files before \texttt{find} even begins.

\item Here is the right way to find files beginning with ``\texttt{c}''
  under the \texttt{/usr/bin} directory:
  \begin{alltt}
$ \textbf{find /usr/bin -name c\bs*}
  \end{alltt}%$
  Note that we need to quote the ``\texttt{*}'', because we want
  \texttt{find} to have the star, we don't want the shell to turn it
  into a list of files starting with ``\texttt{c}'' in the current
  directory.
\item Find man pages that are bigger than 10\,k:
  \begin{alltt}
$ \textbf{find /usr/share/man -size +10k}
  \end{alltt}%$
\item Find man pages that are bigger than 10\,k but smaller than 15\,k:
  \begin{alltt}
$ \textbf{find /usr/share/man -size +10k -size -15k}
  \end{alltt}%$
\item Find man pages that are smaller than 10\,k OR bigger than 15\,k:
  \begin{alltt}
$ \textbf{find /usr/share/man -size -10k -o -size +15k}
  \end{alltt}%$
  We use the logical OR operator ``\texttt{-o}''
\item Find man pages that are smaller than 10\,k but bigger than 15\,k
  and which are ordinary files (not directories or symbolic links):
  \begin{alltt}
\myss$ \textbf{find /usr/share/man -type f \bs( -size -10k -o -size +15k \bsn)}
  \end{alltt}%$
  We need to use parentheses to group the OR operation first,
  otherwise it will test for files that are smaller than 10\,k and
  which are normal files, OR for \emph{any} files that are bigger than
  15\,k.  The parentheses must be quoted or the shell will try to
  start a shubshell.
\end{itemize}



\section{Locate Files ({\cmdn locate})}
\label{sec:basic-linux-unix-tools-locate}

\begin{itemize}
\item {\cmdn locate} searches a periodically-updated database of the
  filesystem(s)
  \begin{itemize}
  \item Not available on all systems
  \item Very fast, but DB needs regular updating, e.g.
\begin{alltt}
$ \textbf{updatedb}
\end{alltt}%$
   \item Usually updated nightly automatically
  \end{itemize}

\item Won't be there on a fresh install
\item Won't show files created since last database update
\item Given the command `{\cmdn locate {\usb string}}', {\pgn locate}
  will show all files containing {\usb string} in their full pathname,
  e.g.
\
\begin{alltt}
$ \textbf{locate logrotate}
/usr/man/man8/logrotate.8
/usr/sbin/logrotate
/etc/logrotate.d
/etc/logrotate.d/cron
/etc/logrotate.d/syslog
/etc/logrotate.d/linuxconf
/etc/logrotate.d/ftpd
/etc/logrotate.d/samba
/etc/cron.daily/logrotate
/etc/logrotate.conf
\end{alltt}%$
\end{itemize}



\section{View and Concatenate Files ({\pgn cat})}
\label{sec:basic-linux-unix-tools-cat}



\begin{itemize}
\item Displays and/or joins (con{}\framebox{cat}enates) files
\item Sends the content of named file(s) to standard output
\item If no filename is given, it reads from standard input and writes to standard output
\item Given more than one filename, it displays each file's contents sequentially, i.e, joins them
\item Example:

\begin{alltt}
$ \textbf{cat file1 file2 file3 > all_files}
\end{alltt}%$

\end{itemize}



\section{View Large Files \& Output ({\pgn less})}
\label{sec:basic-linux-unix-tools-less-more}

\begin{itemize}
\item {\pgn less} displays the contents of file(s) in a controlled way
  on stdout
  \begin{itemize}
  \item Usually, one page at a time
  \item Like UNIX/DOS command {\pgn more}, on steroids
  \end{itemize}
\item  You can search for patterns in the file
\item  It allows you to move quickly to {\em any} point (backwards or  forwards)
\item  Similar usage to {\pgn more}, {\pgn vi}, and {\pgn lynx}:



    \begin{table}[htbp]
      \begin{center}
{\myss
    \begin{tabular}[t]{|>{\PBS\rr}p{210pt}|>{\PBS\rr}p{220pt}|} \hline
Action                                  & Keystokes \\ \hline \hline
Top of page                         & {\kbk g  <  ESC-<}            \\   
Bottom of page                      & {\kbk G  >  ESC->}            \\   
Forward one screen                      & {\kbk f  \^{}F  \^{}V  SPACE}     \\
Backward one screen                     & {\kbk b  \^{}B  ESC-v}          \\
Up one line                             & {\kbk y  \^{}Y  k  \^{}K  \^{}P}    \\
Down one line                           & {\kbk e  \^{}E  j  \^{}N  RETURN}     \\
{\usb pattern} Search forward           & {\kbk /{\usb pattern}}        \\
{\usb pattern} Search backward          & {\kbk ?{\usb pattern}}        \\
Repeat {\usb pattern} Search forward    & {\kbk n}                      \\
Repeat {\usb pattern} Search backward   & {\kbk N}                      \\
Move to {\usb n}th line                 & {\kbk {\usb n}g}       \\  
!command                                & Execute the shell command with \${}SHELL \\
|Xcommand                               & Pipe file between current pos \&\ mark X to shell command  \\
v                                       & Edit the current file with \${}VISUAL or \${}EDITOR  \\ \hline
    \end{tabular}
        \caption{Commands within {\pgn less}}
        \label{tab:commands-in-less}
}
      \end{center}
    \end{table}
  \end{itemize}


\section{Viewing Parts of Files ({\pgn head} and {\pgn tail})}
\label{sec:basic-linux-unix-tools-head-tail}


\begin{itemize}
\item {\pgn head} displays the first few lines of a file  
\item {\pgn tail} displays the last few lines of a file
\item You can specify how many lines are displayed
  \begin{itemize}
  \item To display only the first 4 lines:

{\sco \$ head -4 {\usb filename}} 
  \end{itemize}

\item {\cmdn tail -f} often used to monitor growing files, e.g.,
\begin{alltt}
$ \textbf{sudo tail -f /var/log/messages}
\end{alltt}%$
\end{itemize}






\section{Listing File Information ({\pgn ls})}
\label{sec:basic-linux-unix-tools-ls}

\begin{itemize}
\item Without any options, {\pgn ls} lists files in the current
  directory
\item By default all files starting with {\kbk .} (dot) aren't shown
\item The most common options to {\pgn ls} include:

\vspace{5pt}
  \begin{table}[htbp]
    \begin{center}
{\myss
      \begin{tabular}[t]{|l|>{\PBS\rr}p{333pt}|} \hline
Flag        & Option  \\ \hline \hline
{\cmdn -l}  & {\em Long} (detailed) listing of file info, including: size, ownership, permissions and type\\
{\cmdn -a}  & Show {\em all} files, including hidden ones \\
{\cmdn -F}  & Highlight directories and executables with {\sco /} and {\sco @} respectively \\
{\cmdn -R}  & {\em Recursively} list subdirectories \\

{\cmdn -t}  & Sort list by last modification {\em time} \\
{\cmdn -u}  & Sort list by last access time (with {\cmdn -t}) \\
{\cmdn -X}  & Sort list by file e{\em X}tension \\
{\cmdn -r}  & Reverse order of listing \\
{\cmdn -d}  & Show directory information not directory contents \\ \hline


      \end{tabular}
}
      \caption{Common options to {\pgn ls}}
      \label{tab:common-options-t0-less}
    \end{center}
  \end{table}
  \item For example:
\begin{verbatim}
$ ls -lrt
\end{verbatim}%$
show files in reverse order based on their modification time




\end{itemize}




\section{File Classification ({\pgn file})}
\label{sec:basic-linux-unix-tools-file}

\begin{itemize}
\item {\pgn file} displays the type of data contained in named file(s)
\item It works by:
  \begin{enumerate}
  \item opening each named file
  \item reading the beginning of the file
  \item comparing what it finds there with the patterns in the
    ``magic'' file {\fn /usr/share/magic}
  \item reports the matching file type found in the magic file.
  \end{enumerate}
\item Results not always correct
\item Classifications include: executable, archive, \\C program, ASCII
  text, JPEG image \ldots
\item You can use it like this:
\begin{alltt}
$ \textbf{file /usr/bin/*}
\end{alltt}%$

%% {\myss

%% {\cmdn file [-vbczL] [-f {\usb filename}] [-m {\usb magicfiles}] file\ldots}

%% }

\end{itemize}





\section{Count Words, Lines, Characters ({\pgn wc})}
\label{sec:basic-linux-unix-tools-wc}

\begin{itemize}
\item {\pgn wc} displays the number of lines, words,\footnote{A `word', in this context, is a character string 
    surrounded by SPACEs, TABs, NEWLINEs, or a combination of them.} and characters in a file

\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\mns
\begin{tabular}[t]{|l|p{305pt}|} \hline
Flag       & Option \\ \hline \hline
{\cmdn -l} & Only displays the number of lines \\  
{\cmdn -w} & Only displays the number of `words' \\
{\cmdn -c} & Only displays the number of characters \\ \hline
\end{tabular}
}
      \caption{Options to the {\pgn wc} command}
      \label{tab:wc-options}
    \end{center}
  \end{table}


\end{itemize}






\section{Differences Between Files ({\pgn diff})}
\label{sec:basic-linux-unix-tools-diff}

\begin{itemize}
\item {\pgn diff} displays the difference between two {\em text} files, line-by-line
\item Output from {\pgn diff} can be confusing
\item For example, given the files {\usb text1} and {\usb text2}:



  \begin{quote}
   {\bf text1:} \\
    This is a temprary test \\
    to check the diff  \\
    utility    
  \end{quote}

  \begin{quote}
    {\bf text2:} \\
    This is a temporary test \\
    to check the diff \\
    utility.    
  \end{quote}

\vspace{10pt}
  \begin{enumerate}
\item A simple line-by-line comparison:

  \begin{quote}
\begin{verbatim}
$ diff text1 text2
1c1
< This is a temprary test
---
> This is a temporary test
3c3
< utility
---
> utility.

\end{verbatim}    
%$
  \end{quote}
  \pagebreak


\item Using the context output format ({\cmdn -c}):

\begin{verbatim}
$ diff -c text1 text2
*** text1       Mon Apr 19 14:46:25 1999
--- text2       Mon Apr 19 14:46:05 1999
***************
*** 1,3 ****
! This is a temprary test
  to check the diff
! utility
--- 1,3 ----
! This is a temporary test
  to check the diff
! utility.

\end{verbatim}
%$

\item Using the unified output format ({\cmdn -u}): (Most common)

\begin{verbatim}
$ diff -u text1 text2
--- text1       Mon Apr 19 14:46:25 1999
+++ text2       Mon Apr 19 14:46:05 1999
@@ -1,3 +1,3 @@
-This is a temprary test
+This is a temporary test
 to check the diff
-utility
+utility.
\end{verbatim}%$

  \end{enumerate}

\end{itemize}



\section{Compare Binary Files ({\pgn cmp})}
\label{sec:basic-linux-unix-tools-cmp}

\begin{itemize}
\item Displays differences between 2 {\em binary} files
\item Locates the byte and line number of the first difference
\item Can show {\em all} differences if required, e.g. 
  
  {\cmdn cmp -l {\usb file1} {\usb file2}}
\item {\cmdn cmp -s} suppresses output and returns exit status
  \begin{itemize}
  \item {\sco 0} if the files are identical
\item {\sco 1} if the files differ
\item {\sco 2} if an error has occurred
  \end{itemize}

\item Often used in shell scripts
\end{itemize}



\section{Regular Expression Searches ({\pgn grep})}
\label{sec:basic-linux-unix-tools-grep}

\begin{itemize}
\item Search for regular expressions in file(s)
  \begin{quote}
  {\myss i.e  ``\framebox{g}lobally find \framebox{r}egular \framebox{e}xpressions and \framebox{p}rint''}
  \end{quote}
\item Usage:\\ {\cmdn grep [options] search-pattern files}
\item Reads standard input if no filenames are given
\item Matching lines are printed to standard output
\item Popular options:

\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\myss
      \begin{tabular}[t]{|l|>{\PBS\rr}p{313pt}|} \hline
Flag       &   Option \\ \hline \hline
{\cmdn -i}  &   Ignore case    \\  
{\cmdn -l}  &   List only filenames containing the expression   \\  
{\cmdn -v}  &   Reverse sense of test, i.e. find non-matching lines \\ 
{\cmdn -w}  &   Word search, i.e. match whole word \\ 
{\cmdn -E}  &   Extended regular expression search (more complex patterns), {\pgn egrep} similar  \\
{\cmdn -F}  &   Fixed string pattern search, same as {\pgn fgrep}  \\  \hline
    \end{tabular}
}    
  \caption{Popular {\pgn grep} options}
      \label{tab:popular-grep-options}
    \end{center}
  \end{table}
\end{itemize}  



\section{{\pgn grep} examples}
\label{sec:basic-linux-unix-tools-grep-examples}

\begin{itemize}
  \item Search for a user in the password file
{\myfs \begin{verbatim}
$ grep lee /etc/passwd
lee:x:500:500:Lee Willis:/home/lee:/bin/bash
\end{verbatim}}
%$
  \item Search for events in a log\footnote{You need to be logged in
      as root to see inside /var/log/secure.}
{\myfs \begin{verbatim}
# grep connect /var/log/secure
Mar  8 14:42:53 rafters in.telnetd[579]: connect from 192.168.0.129
Mar 13 10:27:40 rafters in.telnetd[724]: connect from 192.168.0.139
Mar 13 16:54:24 rafters in.telnetd[2135]: connect from 192.168.0.139
Mar 20 10:54:38 rafters in.telnetd[816]: connect from 127.0.0.1
\end{verbatim}}

  \item Search for a function in source code
{\myfs \begin{verbatim}
$ grep "int main" *.cpp
checkrefint.cpp:int mainbit();
checkrefint.cpp:int mainbit(){
do_maint.cpp:int maint(Form &Myform){
expire.cpp:int main(void){
maint_login.cpp:int maint_login(Form &) {
\end{verbatim}}
%$
\end{itemize}



\section{Sort and Merge Files ({\pgn sort})}
\label{sec:basic-linux-unix-tools-sort}

\begin{itemize}
\item {\pgn sort} and/or merge files
\item Acts as a filter without file arguments
\item Sorts entire lines lexically, by default
\item Alternative sort orders: \\[12pt]


  \begin{table}[htbp]
    \begin{center}
{\mns
  \begin{tabular}[t]{|l|p{313pt}|} \hline 
Flag         &           Option \\ \hline \hline
{\cmdn -n}   &           Numerical order \\
{\cmdn -r}   &           Reverse order \\  \hline
  \end{tabular}
}
      \caption{Alternative {\pgn sort} orders}
      \label{tab:alternative-sort-orders}
    \end{center}
  \end{table}
  
\item Other popular options: \\[12pt]

  \begin{table}[htbp]
    \begin{center}
{\myss
      \begin{tabular}{|l|>{\PBS\rr}p{248pt}|} \hline
Flag               &  Option  \\ \hline \hline
{\cmdn -b}         &  Blanks (TAB, SPACE) ignored   \\  
{\cmdn -f}         &  Fold lowercase to upper before sorting \\
{\cmdn -i}         &  Ignore non-printable characters \\
{\cmdn -m}         &  Merge files, without checking if sorted   \\  
{\cmdn -t{\usb x}} &  Set field delimiter in file as {\usb x}   \\  
{\cmdn -u}         &  Unique, outputs repeat lines once only   \\   
{\cmdn -k {\usb POS1[,POS2]}} & Specify a field in each line as a
sorting key, starting at  {\usb POS1}  and  ending at {\usb POS2}
(or NEWLINE).  Fields and character positions are numbered  starting
at 1  \\ \hline
      \end{tabular}
}
      \caption{Popular {\pgn sort} options}
      \label{tab:popular-sort-options}
    \end{center}
  \end{table}
\end{itemize}



\section{{\pgn sort} Examples}
\label{sec:basic-linux-unix-tools-sort-examples}

Consider {\fn /etc/passwd} which typically contains 
lines in the following format:
{\Large {\sco username:password:UID:GID:Realname:Homedirectory:shell}}

\begin{itemize}
\item To sort by username:\\
  {\sco \$ sort -t: -f -k1,1 /etc/passwd}
\item To sort numerically by user ID:\\
  {\sco \$ sort -t: -n -k3,3 /etc/passwd}
\item To sort by real name within group ID:\\
  {\sco \$ sort -t: -k4,4n -k5,5f /etc/passwd}
\end{itemize}
\vspace{16pt}
% This picture does not help at all.
%\begin{center}
%  \includegraphics{../images/basic_tools_sorting}\\[16pt]
%{\cmdn sort -r} 
%\end{center}



\section{Display Unique Lines ({\pgn uniq})}
\label{sec:basic-linux-unix-tools-uniq}

\begin{itemize}

\item Removes all but one of successively repeated lines
\item Acts on standard input, often piped from {\pgn sort}
\item Most popular options:


\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\myss
  \begin{tabular}[t]{|l|>{\PBS\rr}p{313pt}|} \hline
Flag            & Option   \\  \hline \hline 
{\cmdn -c}            & Put a count of how many lines were duplicate
in front of each line  \\
{\cmdn -d}            & Duplicated lines only are displayed \\
{\cmdn -u}            & Unique lines only  are displayed  \\
{\cmdn -{\usb n}}     & Ignore the first {\usb n} fields \\
{\cmdn +{\usb n}}     & Ignore the first {\usb n} characters \\
{\cmdn -w}            & Specify the number of chars to compare \\  \hline
  \end{tabular}
}

      \caption{Popular {\pgn uniq} options}
      \label{tab:popular-uniq-options}
    \end{center}

  \end{table}
  \item Example:\\[16pt]
  \includegraphics{../images/basic_tools_sorting_and_uniq}\\[16pt]

\end{itemize}


\section{Split Files ({\pgn split})}
\label{sec:basic-linux-unix-tools-split}

\begin{itemize}
\item Split a file into pieces
\item Outputs sections to new files or standard output
\item Creates files named {\uin prefixaa}, {\uin prefixab}, 
{\uin prefixac} \ldots
\item Main {\pgn split} options:

\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\myss
  \begin{tabular}[t]{|l|>{\PBS\rr}p{313pt}|} \hline
Flag            & Option   \\  \hline \hline 
{\cmdn -l{\usb n}}    & Put {\usb n} lines of the input file into each output file  \\
{\cmdn -b{\usb n}}    & Put {\usb n} bytes of the input file into each output file \\
{\cmdn -C{\usb n}}    & Put as many complete lines of the input file as is possible into the output file, up to {\usb n} bytes \\  \hline
  \end{tabular}
}

      \caption{Main {\pgn split} options}
      \label{tab:popular-split-options}
    \end{center}
  \end{table}


\section{Splitting Files by Context ({\pgn csplit})}
\label{sec:basic-linux-unix-tools-split-files-by-context}


\item Splits file into sections determined by context (patterns or regular extressions)
\item Syntax:

{\myfs \mbox{\sco csplit  [-f prefix] [-b suffix] [-n digits] {\usb filename} pattern...}}

\item Main {\pgn csplit} arguments:

\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\myss
  \begin{tabular}[t]{|l|>{\PBS\rr}p{257pt}|} \hline
Argument                   & Instruction   \\  \hline \hline 
{\cmdn {\usb /regexp/[offset]}}   & Split the file at occurrence of {\usb regexp}.  The line after the optional offset (`+' or `-' followed by a number) begins next bit of input \\
{\cmdn {\usb \{repeat-count\}}}           & Repeat the previous pattern split {\usb n} times.  Substitute an asterisk for {\usb n} to repeat until the input is exausted \\
{\cmdn -f{\usb string}}    & Use {\usb string} as prefix of output filename  \\
{\cmdn -b{\usb string}}    & Use {\usb string} as suffix of output filename  \\
{\cmdn -n{\usb n}}         & Use output filenames {\usb n} digits long \\ \hline
  \end{tabular}
}

      \caption{Main {\pgn csplit} arguments}
      \label{tab:main-csplit-arguments}
    \end{center}
  \end{table}


\end{itemize}

\section{Dividing files into columns: {\cmdn cut}}
\label{sec:cut}

\begin{itemize}
\item Often need to separate one or more columns from input.
  \begin{itemize}
  \item {\cmdn cut} provides a simple way;
  \item {\cmdn awk} provides another way (more flexible; see later).
  \item Use {\cmdn paste} to join columns together
  \end{itemize}

\item Syntax: \texttt{cut} \meta{options} [\meta{files}]

\item Cuts out the selected columns or fields from one or more
  \meta{files}.
\item Can specify a range of values with a hyphen, and use a comma to
  separate values, e.g., \texttt{1-10,15,20,} or \texttt{50-}
\item Options:

  \begin{description}
  \item[\texttt{-b}, \texttt{--bytes} \meta{list}]
    Specify \meta{list} of positions; only bytes in those positions
    will be printed.
  \item[\texttt{-c}, \texttt{--characters} \meta{list}]
    Cut the column positions given in \meta{list}
  \item[\texttt{-d}, \texttt{--delimiter} \meta{c}]
    Use \texttt{-f} to specify field delimiter as character \meta{c}
    (default is tab); special characters must be quoted.
  \item[\texttt{-f}, \texttt{--fields} \meta{list}]
    Cut the fields given in \meta{list}
  \end{description}

\item Examples:
  \begin{itemize}
  \item Extract usernames and real names from \texttt{/etc/passwd}:
\begin{verbatim}
cut -d: -f1,5 /etc/passwd
\end{verbatim}
  \item Find out who is logged in, but only login names:
\begin{verbatim}
who | cut -d" " -f1
\end{verbatim}

  \item Cut characters from the fourth column of \texttt{file} and
  paste them back as the first column in the same file:
\begin{verbatim}
cut -c4 file | paste - file
\end{verbatim}
  \end{itemize}
\end{itemize}





\section{Compression Utilities: {\pgn bzip2} and {\pgn gzip}}
\label{sec:basic-linux-unix-tools-gzip}

\begin{itemize}
\item Linux has many compression utilities; {\pgn bzip2} and {\pgn
    gzip} dominate thanks to integration with {\pgn tar}, and
    excellent compression
\item Takes files or standard input and compress them to file(s) or standard output
\item Uses {\kwd lossless compression}, so safe on any file
\item Key {\pgn bzip2} and {\pgn gzip} options:

\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\myss
      \begin{tabular}{|l|>{\PBS\rr}p{295pt}|} \hline 
Flag                  &  Option   \\ \hline   \hline
{\cmdn -r}            &  Recursive compression of subdirectories  \\ 
{\cmdn -d}            &  Decompress (same as {\cmdn gunzip})  \\ 
{\cmdn -{\usb [1-9]}} & Fast or best compression, where 1 is fastest and 9 is most intense compression\\ \hline
      \end{tabular}
}
      \caption{Key {\pgn bzip2} and {\pgn gzip} options}
      \label{tab:key-gzip-options}
    \end{center}
  \end{table}

  
\item {\pgn bzip2} has significantly better compression ratios and is
  now widely used for distributing software.
  
\item A set of files put into an archive with {\pgn tar} and {\pgn
    bzip2} gives \emph{much} better compression than can be achieved
  in zip files or rar archives.
\end{itemize}




\section{Store and Retrieve Archives ({\pgn tar})}
\label{sec:basic-linux-unix-tools-tar}

\begin{itemize}
\item Originally designed to make tape archives
\item Takes a group of files and creates one big file containing their
  contents {\em and} details
\item Widely used for:
  \begin{itemize}
  \item Compression with {\pgn gzip} or {\pgn bzip2}~\footnote{The
      {\cmdn gzip} or {\cmdn bzip2} compression
      options are not available on all UNIX versions of {\pgn tar}.}
  \item Maintaining Linux file details (permissions, dates, ownership
    etc) on other filesystems
  \item Bundling file trees for distribution (called a \emph{tarball})
  \end{itemize}



\item Key {\usb tar} options:
\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\myss
      \begin{tabular}{|l>{\PBS\rr}p{313pt}|} \hline 
Flag                  &  Option   \\ \hline   \hline
{\cmdn -t}            &  List files in an archive   \\ 
{\cmdn -x}            &  Extract the contents from an archive  \\ 
{\cmdn -c}            &  Create a new archive   \\ 
{\cmdn -r}            &  Append files to an existing archive  \\
\hline \hline
{\cmdn -v}            &  Verbose: list file names, tell more of what's
happening\\ 
{\cmdn -j}            &  Create/Open bzip2 compressed {\pgn tar} file(s)  \\ 
{\cmdn -z}            &  Create/Open gzip compressed {\pgn tar} file(s)  \\ 
{\cmdn -f}            &  Filename of the file or device to hold the archive   \\ 
{\cmdn -p}            &  preserve permissions when extracting files  \\ \hline
      \end{tabular}
}
      \caption{Key {\pgn tar} options}
      \label{tab:key-tar-options}
    \end{center}
  \end{table}

\vspace{-10pt}
\item To create a {\pgn gzip} compressed archive of {\fn /etc}:

\begin{verbatim}
$ tar -cvzf /home/username/filename.tar.gz /etc
\end{verbatim}
%$
\item To extract the files into the current directory:

\begin{verbatim}
$ tar -xvzf filename.tar.bz2
\end{verbatim}%$

\item To create a {\pgn bzip2} compressed archive of {\fn /etc}:
\begin{verbatim}
$ tar -cvjf /home/username/filename.tar.gz /etc
\end{verbatim}%$

\item To extract the files into the current directory:
\begin{verbatim}
$ tar -xvjf filename.tar.bz2
\end{verbatim}%$
\end{itemize}



\section{Translating Characters ({\pgn tr})}
\label{sec:basic-linux-unix-tools-tr}

\begin{itemize}
\item Translate characters in standard input into different characters in output

\item Syntax:
  
  {\cmdn tr [{\uin options}] [{\usb string1} [{\usb string2}]]}
  

\item Characters in {\usb string1} are replaced by the corresponding
  character in {\usb string2}
\begin{verbatim}
  $ tr `abc` `123`
  abcdad
  123d1d
\end{verbatim}
%$
\item Character position in both strings matters
\item Both strings should be the same length~\footnote{If string1 is
    shorter than string2, the extra characters at the end of string2 are
    ignored.  If string1 is longer, GNU {\pgn tr} follows BSD in padding
    string2 to the length of string1, by repeating the last character. With
    the {\cmdn -t} option it follows AT\&T by truncating string1
    to the length of string2.}
\end{itemize}  

\section{Examples of {\pgn tr} Usage}
\label{sec:basic-linux-unix-tools-egs-tr}


\begin{itemize}
\item To replace all vowels in the input with spaces
\begin{alltt}
$ \textbf{tr 'aeiou' '     '}
\end{alltt}
%$
\item Using character ranges to translate all lower case letters into their upper case equivalents
\begin{alltt}
$ \textbf{tr 'a-z' 'A-Z'}
\end{alltt}
%$
\item Using the asterisk {\kbk *} to replace all 10 digits with the
  same letter `n'.  In other words, \texttt{[n*10]} is the same as
  \texttt{'nnnnnnnnnn'}
\begin{alltt}
$ \textbf{tr '0-9' '[n*10]'}
\end{alltt}
%$
\item Use the {\cmdn -c} option (complement) to replace all
  characters in {\usb string1} which {\em don't} belong in a range
  
\begin{alltt}
$ \textbf{tr -cs 'a-zA-Z0-9' '[\bs{}n*]'}
\end{alltt}
%$
  
  N.B. This puts every word on a line by itself, by converting all
  non-alphanumeric characters to newlines, then `squeezing' repeated
  newlines (with {\cmdn -s}) into a single newline.

  The pattern \texttt{[\bs{}n*]} in the second set means repeat the
  newline \texttt{\bs{}n} as many times as there are characters in the
  first set.  See \texttt{man~tr}.

\end{itemize}



\section{Execute programs at specified times ({\pgn at})}
\label{sec:at-batch}


\begin{itemize}
\item {\pgn at} executes a shell script at a specified time 
\item Syntax:
  
  {\cmdn \$ at [{\usb options}] {\usb time} [{\usb date}] +{\usb
      increment} }
\item \verb|stdin| is scanned for commands to execute, e.g.  
{\myss
\begin{verbatim}
at 2300
at> fetchmail 
<CTRL>+D
\end{verbatim}
    }
\item Some more examples of how to specify time and date: 
{\myss
\begin{verbatim}
at 11pm
at 1am
at 5am tomorrow
at 08:00 Sep 12
at now
at now + 4 hours
at now + 1 day
at now + 2 months
at now + 3 years
at 5:30pm Thursday
at teatime
\end{verbatim}
    }
\item Commands are executed in the current environment at the given
  time
\item \verb|stdout| and \verb|stderr| are sent as mail
\end{itemize}




\section{Options and commands related to {\pgn at}}
\label{sec:at-options}


\begin{itemize}
\item {\pgn at} belongs to a family of utilities for managing
  time-specified commands
{\myss
\begin{tabular}[t]{|>{\PBS\rr}p{90pt}|>{\PBS\rr}p{243pt}|} \hline 
Command            &     Purpose \\ \hline \hline
{\pgn atq}         &     Display list of queued {\pgn at} commands \\ \hline 
{\pgn atrm}        &     Remove queued {\pgn at} commands \\ \hline 
{\pgn batch}       &     Schedule jobs at low CPU loading \\ \hline 
  \end{tabular}
}
\vspace{20pt}
\item All of these can be run as {\pgn at} options:
{\myss
\begin{tabular}[t]{|>{\PBS\rr}p{90pt}|>{\PBS\rr}p{243pt}|} \hline 
Option                &     Purpose \\ \hline \hline
{\cmdn -l}            &     Display list of queued {\pgn at} commands \\ \hline 
{\cmdn -d}            &     Remove queued {\pgn at} commands \\ \hline 
{\cmdn -b}            &     Schedule jobs at low CPU loading \\ \hline 
{\cmdn -f{\usb file}} &     Specify script file in command-line \\ \hline 
{\cmdn -m}            &     Send mail after running {\pgn at}, whatever the {\cmdn stdout} or {\cmdn stderr} \\ \hline 
  \end{tabular}
}
\vspace{20pt}
\item The use of {\pgn at} is controlled by {\fn /etc/at.allow} and {\fn /etc/at.deny}~\footnote{UNIX NOTE: On System V these live in {\fn /usr/lib/cron/}}
\end{itemize}


% Nick: this could really be pruned down a bit.
\section{Running commands regularly ({\pgn crontab})}
\label{sec:tools_basic-crontab}

\begin{itemize}
\item {\pgn crontab} lets you submit job lists at regular times using the {\pgn crond} daemon
\item 2 syntax formats:
\begin{alltt}
$ \textbf{crontab filename}
$ \textbf{crontab [-u username] [options]}
\end{alltt}
\item Options, etc:


\begin{table}[htbp]
{\myts
\begin{tabular}[t]{|p{110pt}|>{\PBS\rr}p{263pt}|} \hline
Command                        & Purpose  \\ \hline \hline
{\cmdn crontab {\usb myfile}}  & Install contents of 
                                 {\usb myfile} (\verb|stdin| if no file 
                                 specified) in appropriate 
                                 directory \\ \hline 
{\cmdn crontab -r}             & Remove the crontab for the current user  \\ \hline
{\cmdn crontab -l}             & List (on \verb|stdout|) current 
                                 user's {\pgn crontab}.  (might 
                                 be useful for editing a cron  table) \\ \hline
{\cmdn crontab -e}             & Run a text editor on your  crontab file  \\ \hline
\end{tabular}
}
    \caption{{\normalsize \pgn crontab} usage}
    \label{tab:crontab-usage}
\end{table}

\item Examples of Crontab Entries

{\myss
\begin{verbatim}
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
# LW poll client1  for mail
0 10,12,16,18 * * 1-5 root /www/bin/client1_poll
LW 16/09/1998 - Hylafax cron stuff ...
0 0 * * *  root /usr/local/sbin/faxqclean
10 0 * * * fax /usr/local/sbin/faxcron -info 7
[0-59/10] 9-18 * * 1-5 root /usr/local/bin/domail
\end{verbatim}
}

\end{itemize}





\section{Evaluate expressions ({\pgn expr})}
\label{sec:linux-unix-tools-evaluate-expressions}


\begin{itemize}
\item {\pgn expr} is used to evaluate expressions, like {\pgn
    bash} arithmetic expressions, e.g., {\uin echo \$((1 + 2))}
\item Takes arguments and operators on the command line
\item Prints the result
\item Also returns true or false depending on the result; can be tested
  with shell---see example with the \texttt{while} loop below.
\item Watch out for special meaning to shell of characters like
  {\kbk*} and {\kbk<} or {\kbk>}
{\myss
\begin{verbatim}
$ expr 1 + 2
3
$ expr 6 \* 7 #must escape the '*'
42
$ expr 5 + 10 / 2
10
$ expr \( 5 + 10 \) / 2
7
$ i=10
$ i=`expr $i + 1`
$ echo $i
11
\end{verbatim}
%$
{\pgn expr} prints 1 for true comparisons, 0 for false.
}
\item Has some string manipulation facilities too:
{\myss
\begin{verbatim}
$ expr index abcdefg d
4
$ expr substr abcdefghijk 3 3
cde
\end{verbatim}
}
\item Sometimes used in shell scripts for looping; \texttt{expr}
  returns false if the expression is null or 0, and true otherwise:
{%\myss
\begin{verbatim}
i=0
while expr $i \< 20 >/dev/null
do
    echo $i
    i=$(expr $i + 1)
done
\end{verbatim}
\item See \texttt{info expr} for details.
}
\end{itemize}



\section{Linux Printing}
\label{sec:basic-linux-unix-tools-linux-printing}
\begin{itemize}
\item Two main printing sytems:
  \begin{itemize}
  \item Common Unix Printing System (\CUPS) \url{http://www.cups.org/}
  \item LPRng \url{http://www.lprng.com/}
  \end{itemize}
\item Both currently provided on Red Hat Linux 8.0 and 9
\item Only \CUPS provides on Fedora Core 1+.
  \begin{itemize}
  \item Can select either system with \texttt{redhat-switch-printer}
    command
  \end{itemize}
\item Expect \CUPS to be more prevalent in future
\end{itemize}

\section{LPRng and CUPS}
\label{sec:lprng-and-CUPS}

\begin{itemize}
\item Completely network-oriented
\item Any printer can be made available to any client (machine and application)
\item All print jobs are sent to a queue
\item Queues can be viewed, edited, maintained from anywhere
  \begin{itemize}
  \item Subject to permission
  \end{itemize}
\item Formatted files can be sent straight to queues
\item Both \CUPS and LPRng both share common printing commands
\end{itemize}


\section{Main Printing Tools}
\label{sec:basic-linux-unix-tools-main-printing-tools}

\begin{itemize}
\item {\pgn lpr} sends job to the queue for a named printer
\item {\pgn lpq} returns info about jobs in a queue
\item {\pgn lprm} removes unwanted jobs from a queue
\item {\pgn lpc} enables system administrator to control the operation
  of the printing system
  \begin{itemize}
  \item see {\cmdn man lpc} for details
  \end{itemize} 
\item Desktop environments may offer ``drag `n' drop'', visual facilities,
  etc
\end{itemize}


\section{Using {\pgn lpr}}
\label{sec:basic-linux-unix-tools-using-lpr}

\begin{itemize}
\item Syntax:
\begin{verbatim}
 lpr [options] file ...
\end{verbatim}
\item Main Options:

\vspace{10pt}
\begin{table}[htbp]
  \begin{center}
    {\mns
      \begin{tabular}{|l|p{313pt}|} \hline
        Flag        & Options \\ \hline \hline
        {\cmdn -P}          & Name of the printer to send the job to \\
        {\cmdn -{\usb n}}  & Print {\usb n} copies of the document  \\ 
        {\cmdn -m}          & Send mail on completion  \\ \hline 
        
      \end{tabular}
    }
    \caption{Main {\pgn lpr} options}
    \label{tab:main-lpr-options}
  \end{center}
\end{table}
\vspace{-10pt}
\item Example:
\begin{verbatim}
$ lpr -Pdjrmt -2 filetypes.txt 
\end{verbatim}
%$
\end{itemize}


\section{Using {\pgn lpq}}
\label{sec:basic-linux-unix-tools-using lpq}

\begin{itemize}
\item Syntax:
\begin{verbatim}
lpq [options]
\end{verbatim}

\item Options:
\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\mns
      \begin{tabular}{|l|p{313pt}|} \hline
Flag        & Options \\ \hline \hline
{\cmdn -P}          & Name of the printer/queue to interrogate \\
{\cmdn -l}          & Get info on each file within a job  \\ \hline 

      \end{tabular}
}
      \caption{{\pgn lpq} options}
      \label{tab:lpq-options}
    \end{center}
  \end{table}
\vspace{-10pt}
\item Example:
\begin{verbatim}
$ lpq -Pdjrmt -l
\end{verbatim}
%$
\end{itemize}



\section{Using {\pgn lprm}}
\label{sec:basic-linux-unix-tools-using-lprm}


\begin{itemize}
\item Syntax:
\begin{verbatim}
lprm [options]
\end{verbatim}

\item Options:

\vspace{10pt}
  \begin{table}[htbp]
    \begin{center}
{\mns
      \begin{tabular}{|l|p{313pt}|} \hline
Flag        & Options \\ \hline \hline
{\cmdn -P}          & Remove jobs from named printer/queue \\
{\cmdn -}           & Remove all jobs belonging to yourself   \\
{\cmdn {\usb user}} & Remove all jobs belonging to {\usb user} \\
{\cmdn {\usb n}}    & Remove job number {\usb n} \\ \hline 

      \end{tabular}
}
      \caption{{\pgn lprm} options}
      \label{tab:lprm-options}
    \end{center}
  \end{table}
\vspace{-10pt}
\item Example:
\begin{verbatim}
$ lprm -Pdjrmt -davef
\end{verbatim}
%$
\end{itemize}


\section{Printing Information}
\label{sec:printing-information}

\begin{itemize}
\item This is a bare introduction
\item See chapter 8 of the \emph{Red Hat Getting Started Guide} (for
  Red hat 9), and

\item chapter 27 of the \emph{Red Hat Customization Guide}
  %\url{http://www.redhat.com/docs/manuals/linux/RHL-8.0-Manual/custom-guide/ch-printing.html}
\item All these are available on the documentation \CDROM, or can be
  downloaded from \url{http://www.redhat.com/docs/manuals/linux/}.
\end{itemize}



\section{Basic Tools Exercises}
\label{sec:basic-linux-unix-tools-exs}
{\normalsize

In these exercises, you will combine simple tools together using
\emph{pipes}.  Do this one step at a time, and check the results as
you go.
\begin{enumerate}
  
  
  
  

\item {\em Find and Locate Files}\\
  Use first {\pgn find} \emph{then} {\pgn locate} to do each of the
  following.  First read \S\vref{sec:basic-linux-unix-tools-find} to
  \S\vref{sec:basic-linux-unix-tools-locate}, especially
  \S\vref{sec:find-examples}.  Also, please read
  \S\vref{sec:basic-linux-unix-tools-tr} and
  \S\vref{sec:basic-linux-unix-tools-egs-tr} before doing part
  \ref{itm:translate}.
\begin{enumerate}
\item Display all the filenames under {\fn /usr/sbin}.
\item Display all the filenames under {\fn /usr/sbin}  begining with a lowercase `{\kbk c}'.
\item \label{itm:translate}Repeat the previous question, but {\em
    translate} the output to uppercase.
\item Display all the files under {\fn /usr/sbin} which are over 5k in size in uppercase.
\end{enumerate}

\item {\em Display Parts of Files}
  
  Note that the file \texttt{mime.types} lists the standard names used
  for different file types in both http and email.  Before sending any
  data, a web server sends a header which includes the \emph{mime
    type}.  That is how the web browser knows what to do with the data
  (i.e., how to display it or play it).  Similarly, email containing
  attachments puts a mime type header before each attachment.  That is
  how the email client knows what to do with the attachment (such as
  to automatically execute it and infect the machine with a worm).
\begin{enumerate}
\item Display the first 10 lines of the file {\fn /etc/mime.types}
\item Display the last  10 lines of {\fn /etc/mime.types}
\item Display the first 25 lines of {\fn /etc/mime.types}
\item Display {\fn /etc/mime.types} one screen at a time
\item While viewing {\fn /etc/mime.types} page-by-page, search for `html'
\end{enumerate}




\item {\em Classify, Count and Compare Files}


\begin{enumerate}
\item Find out what file types you have in the following directories
  and below.  Please read \S\vref{sec:basic-linux-unix-tools-file}.
  Please also see the example on the bottom of
  \S\vref{sec:basic-linux-unix-tools-find}.
  \begin{enumerate}
  \item {\fn /etc}
  \item {\fn /usr/bin}
  \end{enumerate}
  
\item Repeat the previous question, but this time:
  \begin{enumerate}
  \item Re-direct {\fn /etc} listing to new file {\fn
    filetypes.txt}
\item Append the listing for {\fn /usr/bin} to {\fn filetypes.txt}.
  Please refer to
  \S\vref{sec:basic-shell-and-tools-approach-output-redirection}.
  \end{enumerate}
  
\item Build a tool (i.e. write a command) to find out how many files
  are in the {\fn /usr/bin} directory.  Hint: consider using
  \texttt{wc}.
  
\item Create two new files from listings of 2 user's home directories,
  then find the differences between them.

  To do this, you could:
  \begin{itemize}
  \item Find a neighbour you can work with, and open a terminal window
    on their computer
  \item In that terminal window, type:
\begin{alltt}
$ \textbf{su - 012345678}      
\end{alltt}%$
(assuming your user \ID is 012345678).  Of course, you need to enter
your password.
  \item Make a list of files from your home directory into
    \texttt{/tmp}, making sure that the file names do not have
    \texttt{/home/012345678} in front of them, or otherwise your files will all
    seem to have different names!
  \item Compare your file list with that generated by your neighbour,
    who should also put their file list into \texttt{/tmp}.
  \end{itemize}
%\item If you are feeling adventurous, use {\pgn diff} and {\pgn patch}
\item Use {\pgn diff} and {\pgn patch} to make the two files created
  in the last question identical. (Check {\cmdn man patch})
%% \item If you are feeling very adventurous, use {\pgn diff} and {\pgn ed}
%%   to make the two files created in the last question identical. (Check
%%   {\cmdn man ed})
\end{enumerate}

%\item {\em Regular Expressions}
\item  {\em\cmdn grep}

Use the {\fn filetypes.txt} file that you created before, and do the
following.  Please read \S\vref{sec:basic-linux-unix-tools-grep}
and \S\vref{sec:basic-linux-unix-tools-grep-examples} first.

\begin{enumerate}
\item List all the lines that contain `directory'
\item List all the lines that don't contain `directory'.
\item Find out how many files {\em are} directories, then find out how
  many aren't.
\item Why does the following give an error message (try redirecting
  the output to \path{/dev/null} so you can see the error).
\begin{alltt}
$ \textbf{grep ASCII text filetypes.txt}
\end{alltt}%$

\item Find out how many {\tt English text} files are listed in the {\fn
    filetypes.txt} file.
\end{enumerate}


\item {\em Sorting}


\begin{enumerate}
\item Sort the {\fn filetypes.txt} file into reverse alphabetical order on the
  first field.  Please see \S\vref{sec:basic-linux-unix-tools-sort}
  and \S\vref{sec:basic-linux-unix-tools-sort-examples} first.

You may notice that capital and lowercase letters are sorted
independently, e.g. `{\tt A}' comes before `{\tt a}'.
\item Repeat the first sorting exercise but ignoring case differences
\item Sort the {\fn filetypes.txt} files into alphabetical order on the second
  field (the file type).
\end{enumerate}
\end{enumerate}


\section{Basic Tools Solutions}
\label{sec:basic-linux-unix-tools-solutions}

\includeversion{Solutions}%
\excludeversion{noSolutions}%

\begin{Solutions}
\begin{enumerate}
\item {\em Find and Locate Files}

\begin{enumerate}
\item Either 
\begin{alltt}
$ \textbf{find /usr/sbin}
\end{alltt}
%$

or
\begin{alltt}
$ \textbf{locate '/usr/sbin/*'}
\end{alltt}
%$
Note that the quotes are very important.  If you leave them out, the
program will run much more slowly, and the output will be wrong.  Why?

\item Either

\begin{alltt}
$ \textbf{find /usr/sbin -name "c*"}
\end{alltt}
%$
Why is {\cmdn find /usr/sbin/c*} wrong?  Why are the quotes important
around the {\cmdn c*}?

or
\begin{alltt}
$ \textbf{locate '/usr/sbin/c*'}
\end{alltt}%$
The quotes are \emph{really} important for speed and correctness.
Why?  If you do 
\begin{alltt}
$ \textbf{locate /usr/bin/c\bs* | wc -w}
     23
\end{alltt}%
Very fast because only lookup one pattern in the database.
\begin{alltt}
$ \textbf{locate /usr/sbin/c* | wc -w}
     30
\end{alltt}%$
Very slow because need look up 23 patterns in the database.

Many file names are shown twice; for example, if you do:

\begin{alltt}%
$ \textbf{locate /usr/bin/cc /usr/bin/ccexample}
/usr/bin/cc
/usr/bin/ccexample
/usr/bin/ccexample
\end{alltt}%$
We get three results, not two, since \path{/usr/bin/cc} matches
\path{/usr/bin/ccexample} as well as itself.

\item Either 

\begin{alltt}
$ \textbf{find /usr/sbin -name c\bs* | tr 'a-z' 'A-Z'}
\end{alltt}
%$

or
\begin{alltt}
$ \textbf{locate '/usr/sbin/c*' | tr 'a-z' 'A-Z'}
\end{alltt}
%$

\item 
\begin{alltt}
$ \textbf{find /usr/sbin -size +5k | tr 'a-z' 'A-Z'}
\end{alltt}
%$
You should check that the size is correct.  One way to do that is:
\begin{alltt}
$ \textbf{find /usr/sbin -size +5k -ls | sort -k5nr}
\end{alltt}
%$
What are the arguments to {\cmdn sort} for?  Try looking at the
output of {\cmdn find /usr/sbin -size +5k -ls} first.
\end{enumerate}

\item {\em Display Parts of Files}

\begin{enumerate}
\item
\begin{alltt}
$ \textbf{head /etc/mime.types}
\end{alltt}%$

\item
\begin{alltt}
$ \textbf{tail /etc/mime.types}
\end{alltt}%$

\item
\begin{alltt}
$ \textbf{head -n 25 /etc/mime.types}
\end{alltt}%$

\item Use one of the following
\begin{alltt}
$ \textbf{less /etc/mime.types}
\end{alltt}%$
or
\begin{alltt}
$ \textbf{more /etc/mime.types}
\end{alltt}
%$

\item While in one of the above, type

{\uin /html {\kbk <RETURN>}}
\end{enumerate}

\item {\em Classify, Count and Compare Files}

\begin{enumerate}

\item Use these commands:
  \begin{enumerate}
  \item 
\begin{alltt}
$ \textbf{find /etc -exec file \{\} \bs;}
\end{alltt}%$
Note that the following will not execute \texttt{file} on files in
subdirectories of \texttt{/etc}:
\begin{alltt}
$ \textbf{file /etc/*}
\end{alltt}
%$
  \item
\begin{alltt}
$ \textbf{find /usr/bin -exec file \{\} \bs;}
\end{alltt}%$

\end{enumerate}


\item Use these commands  
\begin{enumerate}
  \item 
\begin{alltt}
$ \textbf{find /etc -exec file \{\} \bs; > filetypes.txt}
\end{alltt}%$
\item
\begin{alltt}
$ \textbf{find /usr/bin -exec file \{\} \bs; >> filetypes.txt}
\end{alltt}%$
\end{enumerate}

\item The easiest solution is
\begin{alltt}
$ \textbf{echo /usr/bin/* | wc -w}
\end{alltt}%$
But that will count any file with a space in its name as two files.
This will count all files only once:
\begin{alltt}
$ \textbf{ls -d /usr/bin | wc -l}
\end{alltt}%$
Note that when \texttt{ls} sends its output to a pipe, it always puts
it in one column, so that there is one file per line.  See
\texttt{man~ls}.

\item Something like this:

\begin{alltt}
$ \textbf{cd}
$ \textbf{find . > /tmp/test1.txt}
$ \textbf{cp /tmp/test1.txt \(\sim\)}
\end{alltt}%$
Now another student logs into another window:
\begin{alltt}
$ \textbf{su - 012345678}
Password:
$ \textbf{find . > /tmp/test2.txt}
$ \textbf{cp /tmp/test1.txt /tmp/test2.txt \(\sim\)}
$ \textbf{diff -u test2.txt test1.txt > file-diff.patch}
$ \textbf{less file-diff.patch}
$ \textbf{exit}
\end{alltt}
And you can copy the second students file list into your own
directory:
\begin{alltt}
$ \textbf{cp /tmp/test2.txt \(\sim\)}
$ \textbf{diff -u test1.txt test2.txt > my-file-diff.patch}
$ \textbf{less file-diff.patch}
\end{alltt}%$

Make sure you understand the format of \texttt{diff -u}, and given
output from \texttt{diff} and the original file, can determine what
the second file contains.

%% \begin{alltt}
%% $ \textbf{ls /home/davef > test1.txt}
%% $ \textbf{ls /home/mikeb > test2.txt}
%% $ \textbf{diff test1.txt test2.txt}
%% \end{alltt}%$
  
\item This technique is very important in software development and
  software packaging:
\begin{alltt}
$ \textbf{diff -u test1.txt test2.txt > test.patch}
$ \textbf{patch < test.patch}
patching file test1.txt
\end{alltt}

%% \item This solution uses the {\cmdn -{}-ed} option to {\pgn diff}, and the
%%   {\pgn ed} line-editor.

%% \begin{alltt}
%% $ \textbf{diff --ed test1.txt test2.txt > differences.txt}
%% $ \textbf{cat >> differences.txt
%% w
%% q
%% <CONTROL>d}
%% $ \textbf{cat differences.txt | ed test1.txt}
%% \end{alltt}
%% %$

%% You could instead use the {\pgn sed} 
%%  stream editor to perform the
%% editing in one pipeline.

\end{enumerate}


%\item {\em Regular Expressions}
\item  {\em\cmdn grep}

\begin{enumerate}
\item
\begin{alltt}
$ \textbf{grep directory filetypes.txt}
\end{alltt}
%$
  
\item
\begin{alltt}
$ \textbf{grep -v directory filetypes.txt}
\end{alltt}
 
%$
\item Use either
\begin{alltt}
$ \textbf{grep -c directory filetypes.txt}
\end{alltt}%$
or
\begin{alltt}
$ \textbf{grep directory filetypes.txt | wc -l}
\end{alltt}%$
  
then either
\begin{alltt}
$ \textbf{grep -cv directory filetypes.txt}
\end{alltt}%$
or
\begin{alltt}
$ \textbf{grep -v directory filetypes.txt | wc -l}
\end{alltt}%$

        
        
\item Without escaping the space between {\em ASCII} and {\em text}
  the shell assumes the pattern has ended and takes {\em text} as a
  filename to look for; hence the error about a non-existing file.
  {\pgn grep} continues, however, showing lines that match "ASCII" in
  the files it can find.
  
  What you probably wanted was:
\begin{alltt}
$ \textbf{grep "ASCII text" filetypes.txt}
\end{alltt}
%$

\item 
\begin{alltt}
$ \textbf{grep -c "English text" filetypes.txt}
\end{alltt}
%$

\end{enumerate}


\item {\em Sorting}

\begin{enumerate}
\item
\begin{alltt}
$ \textbf{sort -r filetypes.txt}
\end{alltt}
%$

\item
\begin{alltt}
$ \textbf{sort -fr filetypes.txt}
\end{alltt}
%$

\item
\begin{alltt}
$ \textbf{sort -k2 filetypes.txt}
\end{alltt}
%$

\end{enumerate}


\end{enumerate}
\end{Solutions}
\begin{noSolutions}
  We will provide solutions soon.
\end{noSolutions}

\label{endofchapter-basic-linux-unix-tools}
} % Ends {\normalsize
} % end {\mns from chapter start

\excludeversion{Solutions}%
\includeversion{noSolutions}%

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "toolsmaster"
%%% End: 
