List all files in /bin that start with the letter g
ls /bin/g*
List all files in /bin that end with the letter t
ls /bin/*t
List all files in /bin that start with the letter g and end with the letter t, where the second letter is not e
ls /bin/g[^e]*t
Write a script texter.sh that accepts any number of command line arguments.
It should create a text file using the first argument as the file name and the second argument as the file content.
Repeat for all remaining arguments. If there is an odd number of arguments, leave the last file blank.
> ./texter.sh f1 "this is file 1 content" f2 "deadbeef"
> ls
f1 f2
> cat f1
this is file 1 content
> cat f2
deadbeef
#!/bin/bash
while [[ $# -gt 0 ]]
do
echo $2 > $1
shift
shift
done
Write a script sizes.sh which prints stats about each file in the current directory.
For each file it should print the filename and file size
After printing data for all files, print the size and name of the largest file, then print the sum of all the file sizes.
Your script should ignore directories.
Hint: You can obtain the size of a file as a number by using wc -c with cut
> ./sizes.sh
160786 Alice_in_Wonderland.txt
448821 Frankenstein.txt
2525 cool_online_game.csv
363 sizes.sh
4320 lots_of_the.txt
2549 updated_cool_online_game.csv
Largest is 448821 in Frankenstein.txt
Sum is 619364
#!/bin/bash
sum=0
max_size=0
max_name=''
for f in *
do
if [[ -f $f ]]
then
size=$(wc -c $f | cut -f1 -d " ")
echo "$size $f"
if [[ $size -gt $max_size ]]
then
max_size=$size
max_name=$f
fi
sum=$((sum + size))
fi
done
echo "Largest is $max_size in $max_name"
echo "Sum is $sum"
Modify sizes.sh to accept the command line options as specified below. Use shift and case to achieve this:
-d DIRECTORY Count files in DIRECTORY instead of .
-h Display this help message and exit
#!/bin/bash
sum=0
max_size=0
max_name=''
dir='.'
while [[ $# -gt 0 ]]
do
case $1 in
-h) echo -d DIRECTORY Count files in DIRECTORY instead of .
echo
echo -h Display this help message and exit
exit 0;;
-d) if [[ -z $2 ]]
then
echo "Missing operand for -d argument"
exit 1
fi
dir=$2
shift;;
*) echo "Unknown argument $1"
exit 2;;
esac
shift
done
for f in $dir/*
do
if [[ -f $f ]]
then
size=$(wc -c $f | cut -f1 -d " ")
echo "$size $f"
if [[ $size -gt $max_size ]]
then
max_size=$size
max_name=$f
fi
sum=$((sum + size))
fi
done
echo "Largest is $max_size in $max_name"
echo "Sum is $sum"
You can definitely improve on this, for instance by cleaning up the output and checking if wc falls over.
When would you prefer a while loop over a for loop? When would you prefer a for loop? What is a danger of using a while loop?
While loops are good when you will be looping for an indeterminate amount of time (eg until a variable changes, while waiting for another
process, or while waiting for user input). For loops are good for looping over a fixed set of data or a fixed range of numbers.
While loops require you to manually update the loop condition, otherwise you can get stuck in an infinite loop.
Bonus
Modify sizes.sh to accept the following command line option:
-r Instead of ignoring directories, recursively run stats.sh in each directory found.
Department of Computer Science & Software Engineering
The University of Western Australia
Last modified: 26 April 2023
Modified By: Michael Wise