Bash Exercise (Solutions)

Do the following exercises. Feel free to use man, or <command> --help or even Google to find solutions. Avoid copy and pasting solutins though - we want you to learn how to do these operations fluently, and typing the commands will help.

0. Clean up

This will remove the docs folder in your home direcotry if you have one.

In [1]:
rm -rf ~/docs

1. Creating text files

Create a file with the following contents in a new docs folder in your home directory

first,last,middle,age,sex
Jane,Frost,G,23,F
John,Mundy,F,25,M
Bob,Evans,H,57,M
John,Smith,M<4,M
  • First make the docs folder in your home directory and make that your working directory
In [2]:
cd
mkdir docs
cd docs

Use the following ways to create the document

  • Using echo and redirection (save as echo.txt)
In [3]:
echo 'first,last,middle,age,sex' > echo.txt
echo 'Jane,Frost,G,23,F' >> echo.txt
echo 'John,Mundy,F,25,M' >> echo.txt
echo 'Bob,Evans,H,57,M' >> echo.txt
echo 'John,Smith,M,4,M' >> echo.txt
In [4]:
cat echo.txt
first,last,middle,age,sex
Jane,Frost,G,23,F
John,Mundy,F,25,M
Bob,Evans,H,57,M
John,Smith,M,4,M
  • Using cat and a heredoc (save as cat.txt)
In [5]:
cat <<EOF > cat.txt
first,last,middle,age,sex
Jane,Frost,G,23,F
John,Mundy,F,25,M
Bob,Evans,H,57,M
John,Smith,M,4,M
EOF
In [6]:
cat cat.txt
first,last,middle,age,sex
Jane,Frost,G,23,F
John,Mundy,F,25,M
Bob,Evans,H,57,M
John,Smith,M,4,M
  • Opening a terminal window and using a nano text editor (save as editor.txt). You can also use emacs or vi if you are familiar with these traditional editors.
In [7]:
# Simulate using editor
# You should not do this!

cp cat.txt editor.txt

2. File and directory management.

  • Display your current working directory
In [8]:
pwd
/home/cliburn/docs
  • Change your working directory to your hoem directory if not already there
In [9]:
cd
  • List the contents of the docs folder in your home directory
In [10]:
ls docs
cat.txt  echo.txt  editor.txt
  • Make a new directory stuff within the docs folder
In [11]:
mkdir docs/stuff
  • Move the files cat.txt and editor.txt to the stuff folder
In [12]:
cd docs
mv cat.txt editor.txt stuff
  • Copy the file echo.txt to the stuff folder as echoecho.txt
In [13]:
cp echo.txt stuff/echoecho.txt
  • Show the contents of the docs directory recursively
In [14]:
ls -R ~/docs
/home/cliburn/docs:
echo.txt  stuff

/home/cliburn/docs/stuff:
cat.txt  echoecho.txt  editor.txt
  • Remove the stuff directory and everything in it
In [15]:
rm -rf stuff
cd
ls -R docs
docs:
echo.txt

3. Working with text files

  • Display the contents of echo.txt without the header (first) line
In [16]:
tail +2 docs/echo.txt
Jane,Frost,G,23,F
John,Mundy,F,25,M
Bob,Evans,H,57,M
John,Smith,M,4,M
  • Display the contents of echo.txt sorted by first name (do not display the first row)
In [17]:
tail +2 docs/echo.txt | sort -t',' -k 1
Bob,Evans,H,57,M
Jane,Frost,G,23,F
John,Mundy,F,25,M
John,Smith,M,4,M
  • Display the contents of echo.txt sorted by age in descending order (do not display the first row)
In [18]:
tail +2 docs/echo.txt | sort -t',' -rn -k 4
Bob,Evans,H,57,M
John,Mundy,F,25,M
Jane,Frost,G,23,F
John,Smith,M,4,M
  • Display only lines that contain John
In [19]:
grep 'John' docs/echo.txt
John,Mundy,F,25,M
John,Smith,M,4,M
  • Display only lines that do not contain John
In [20]:
grep -v 'John' docs/echo.txt
first,last,middle,age,sex
Jane,Frost,G,23,F
Bob,Evans,H,57,M
  • Display only lines that contain 4-letter words starting with J
In [21]:
grep 'J...' docs/echo.txt
Jane,Frost,G,23,F
John,Mundy,F,25,M
John,Smith,M,4,M
  • Save only the first three columns of data sorted by last name to a new file names.txt in the docs folder (do not display the first row))
In [22]:
cat docs/echo.txt | cut -d ',' -f 1-3 | tail +2 | sort -t ',' -k 2 > docs/names.txt
In [23]:
cat docs/names.txt
Bob,Evans,H
Jane,Frost,G
John,Mundy,F
John,Smith,M

Optional challenging exercises

  • Display the contents of echo.txt but changing all occurrences of John to Tom
In [24]:
cat docs/echo.txt | sed 's/John/Tom/g'
first,last,middle,age,sex
Jane,Frost,G,23,F
Tom,Mundy,F,25,M
Bob,Evans,H,57,M
Tom,Smith,M,4,M
  • Save only the rows corresponding to males to a new file male.txt in the docs folder. (do not display the first row))
In [25]:
cat docs/echo.txt | awk 'BEGIN {FS = ","} ; $5 == "M"' > docs/male.txt
In [26]:
cat docs/male.txt
John,Mundy,F,25,M
Bob,Evans,H,57,M
John,Smith,M,4,M
In [27]:
ls docs
echo.txt  male.txt  names.txt

Looping

  • Using a for loop, save lines 2-3 of each file in the docs folder as a new file with a name that looks like <originaal name>-copy.txt in a folder with a name like <originaal name>.
  • Upon completiton, ls -R ~/docs should have this structure
/home/cliburn/docs:
echo  echo.txt  male  male.txt  names  names.txt

/home/cliburn/docs/echo:
echo-copy.txt

/home/cliburn/docs/male:
male-copy.txt

/home/cliburn/docs/names:
names-copy.txt
  • Upon completioin, wc ~/docs/*/* shouod show this
2  2 36 docs/echo/echo-copy.txt
2  2 34 docs/male/male-copy.txt
2  2 26 docs/names/names-copy.txt
6  6 96 total

Hints:

  • Use variables to store path and file names (convetnion for variable names is ALL_CAPS_WITH_UNDERSCORES)
  • Use globbig with ls to show the full path to a file
  • The direcotry part of a path can be extracted with dirname
  • The filename part of a path can be extracted with basename
  • You can remove the file extension of a filename stored in X with Y=${X%.*}
  • Experiment using the above hints with simple one line commands to understand what they do
  • Use echo statements in your for loop to see what is going on
In [28]:
for FILE in $(ls ~/docs/*)
do
    DIR_NAME=$(dirname $FILE)
    FILE_NAME=$(basename $FILE)
    NAME=${FILE_NAME%.*}
    NEW_DIR=$DIR_NAME/$NAME
    NEW_FILE=${NAME}-copy.txt
    mkdir -p $NEW_DIR
    cat $FILE | head -3 | tail -2  > $NEW_DIR/$NEW_FILE
done
In [29]:
ls -R ~/docs
/home/cliburn/docs:
echo  echo.txt  male  male.txt  names  names.txt

/home/cliburn/docs/echo:
echo-copy.txt

/home/cliburn/docs/male:
male-copy.txt

/home/cliburn/docs/names:
names-copy.txt
In [30]:
wc docs/*/*
 2  2 36 docs/echo/echo-copy.txt
 2  2 34 docs/male/male-copy.txt
 2  2 26 docs/names/names-copy.txt
 6  6 96 total