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 asecho.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 aheredoc
(save ascat.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 aseditor.txt
). You can also useemacs
orvi
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 thedocs
folder
In [11]:
mkdir docs/stuff
- Move the files
cat.txt
andeditor.txt
to thestuff
folder
In [12]:
cd docs
mv cat.txt editor.txt stuff
- Copy the file
echo.txt
to thestuff
folder asechoecho.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 thedocs
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 ofJohn
toTom
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 thedocs
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
withls
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
withY=${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