Home > Undergraduate > Open Source Tools and Scripting >    Labs

  CITS4407/CITS2003 OPEN SOURCE TOOLS AND SCRIPTING
 
 

Lab 3: Files

In today's lab, you will be writing files. As you will have seen in the lectures, you can write and append to files using output redirects from commands:

echo "#!/bin/sh" > myscript.sh

This is very convenient for command output but it's not a pleasant, interactive editing experience. For that, you will need to use an editor! In this course we will teach you how to use vim (a modern version of the powerful vi editor). Vim is a powerful plain text editor, meaning that it writes pure ascii text without markups (so no fonts or formatting like you'd see in a word processor like Microsoft Word or TextEdit). To open it, simply type vim and the name of the file you wish to edit.

The big difference between vim and other editors is that vim has multiple modes:

  • Normal mode is what you get when you open vim. In this mode you can navigate the file, but you CANNOT ENTER TEXT! Keypresses will do unusual things when you press them. For example, G and / allow you to move and search as you would in less. You can move about the file using arrow keys or h,j,k,l keys. To return to normal mode from another mode, press the Escape key.
  • Insert mode allows you to edit text. To enter insert mode, type i.
  • Command mode allows you to enter commands. To enter command mode, type : and then enter your command. Press Enter to execute your command. Important commands are w to write (save) a file and q to quit vim.

Vim has additional modes for selecting text and replacing text, but those three will be enough to get you started.

That should be enough to get you started. If you want to run through a full tutorial on vim, run vimtutor. For a quick cheat sheet on vim commands, see https://vim.rtorr.com/.

HELP! I am stuck in vim! Press the escape key to return to normal mode. Then save and exit by typing :wq. If you wish to exit without saving, type q!.

Questions

  1. What is the difference between the following sets of commands?
    1. cd /lab
      cd ./week3
      head foo.txt
    2. cd /lab/week3
      head foo.txt
    3. head /lab/week3/foo.txt
    4. head /lab/week3/../week3/../../lab/week3/./././foo.txt

  2. No difference: they all do the same thing

  3. What would you expect to see in each of the following files, based on the file extension?
    1. stuff.txt: a human-readable text file
    2. stuff.sh: an executable shell script
    3. stuff.jpg: an image (not readable as raw text)
    4. stuff: could be anything. Most likely a directory or an executable of some kind

  4. There is a copy of Frankenstein in this week's directory, but it is compressed (zipped).
    1. How big is the compressed copy of Frankenstein?
    2. ls -l # 169453 bytes
    3. Compress Alice in Wonderland. How does it compare to Frankenstein?
    4. gzip Alice_in_Wonderland.txt
      ls -l
      
    5. Uncompress both files and compare their uncompressed sizes.
    6. gunzip Alice_in_Wonderland.txt
      gunzip Frankenstein.txt
      ls -l
      
  5. The following questions refer to arcade.csv, which holds user data for an online game. Solve them using cut, sort, head, tail, uniq.
    1. How many teams are there?
    2. tail arcade.csv -n +2 | cut -d, -f2 | sort | uniq | wc -l    # 4
      
    3. How many unique score values are there?
    4. tail arcade.csv -n +2 | cut -d, -f6 | sort | uniq | wc -l # 361
      
    5. List any duplicate passwords
    6. tail arcade.csv -n +2 | cut -d, -f4 | sort | uniq -d # no repeated passwords
      
    7. Which player had the top score? Note: You will need the sort flags -k, -t and -n for this. Check the man page!
    8. tail arcade.csv -n +2 | sort -k 6 -t, -n  | tail -n1 # Livia
      
    9. Write a pipeline that prints which machine was used by the most players. You will need uniq -c
    10. tail arcade.csv -n +2 | cut -d, -f3 | sort | uniq -c | sort -n | tail -n1 # 136 b
      
    11. You are adding a high score screen for your game which will display the Score column first, then the Player, then Team. No other columns will be shown, and data should be sorted with the highest score appearing first. Write a series of commands to do this using cut and paste.
    12. cut -d, -f1,2 < arcade.csv > player.txt
      cut -d, -f6 < arcade.csv > score.txt
      paste -d, score.txt player.txt | sort -t',' -k 1nr
      
      (This solution requires a little more work. Can you see why?)

  6. Your friend has just sent you some data for her own game in cool_online_game.csv. Use comm to compare this with your data in arcade.csv.
    1. How many players played both games?
    2. tail cool_online_game.csv -n +2 | cut -d, -f 1 | sort > cool_names.txt
      tail arcade.csv -n +2 | cut -d, -f 1 | sort > arcade_names.txt
      comm arcade_names.txt cool_names.txt -12 | wc -l # 215
      
    3. Which players only played your friend's game?
    4. comm arcade_names.txt cool_names.txt -13
      
  7. In the week3 directory there is a script called runme.sh, but it is not executable. Modify this script so that any user can run it with ./runme.sh.
  8. chmod +x /lab/week3/runme.sh
  9. In the week3 directory there is a file called DENIED.txt. Print the contents of this file to the terminal.
  10. chmod 600 DENIED.txt; cat DENIED.txt
  11. Your friend has a broken keyboard, and has written an email (woonky.txt) to the keyboard company asking for repairs. Unfortunately, the keyboard problem has ruined the letter. Write a pipeline using tr to fix the email.
    tr '0' 'o' < woonky.txt | tr -s '[A-Za-z]'
    
  12. Use head, tail and | to construct a pipeline which prints line 999 from Alice_in_Wonderland.txt. A pipeline is a series of commands connected together by pipes (eg. date | wc).
  13. head Alice_in_Wonderland.txt -n 999 | tail -n 1
  14. There is a fun command called cowsay which works like echo but adds some decoration to the input string. To try it out, type cowsay moo. We will make our own version of cowsay called sandwichsay that prints the input string between two slices of bread. For example, ./sandwichsay "ham and cheese" should look like this:
    %============================%
    ham and cheese
    %============================%
    

    Each slice of bread should be approximately 30 characters wide. Feel free to change the appearance of the sandwich if you like.
    Note: Make sure you surround your input string in double quotes ("input") so that it is treated as a single command-line argument by your script. Otherwise each space in your input string will begin a new argument.
  15. #!/bin/bash
    
    echo "%============================%"
    echo "$1"
    echo "%============================%"
    
  16. Modify sandwichsay so that instead of printing to the terminal, it appends output to sandwiches.txt.
  17. #!/bin/bash
    
    echo "%============================%" >> sandwiches.txt
    echo "$1" >> sandwiches.txt
    echo "%============================%" >> sandwiches.txt
    

Bonus

  1. Can you make cowsay print something other than a cow?


Department of Computer Science & Software Engineering
The University of Western Australia
Last modified: 10 April 2023
Modified By: Daniel Smith

UWA