Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #518 for 07-find #528

Merged
merged 8 commits into from
Apr 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
105 changes: 88 additions & 17 deletions _episodes/07-find.md
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,11 @@ about them."
> 2. `grep -E "of" haiku.txt`
> 3. `grep -w "of" haiku.txt`
> 4. `grep -i "of" haiku.txt`
>
> > ## Solution
> > The correct answer is 3, because the `-w` flag looks only for whole-word matches.
> > The other options will all match "of" when part of another word.
> {: .solution}
{: .challenge}

> ## `find` Pipeline Reading Comprehension
Expand All @@ -514,20 +519,39 @@ about them."
> wc -l $(find . -name '*.dat') | sort -n
> ~~~
> {: .bash}
>
> > ## Solution
> > 1. Find all files with a `.dat` extension in the current directory
> > 2. Count the number of lines each of these files contains
> > 3. Sort the output from step 2. numerically
> {: .solution}
{: .challenge}

> ## Matching and Subtracting
>
> The `-v` flag to `grep` inverts pattern matching, so that only lines
> which do *not* match the pattern are printed. Given that, which of
> the following commands will find all files in `/data` whose names
> end in `ose.dat` (e.g., `sucrose.dat` or `maltose.dat`), but do
> *not* contain the word `temp`?
> end in `s.txt` (e.g., `animals.txt` or `planets.txt`), but do
> *not* contain the word `net`?
> Once you have thought about your answer, you can test the commands in the `data-shell`
> directory.
>
> 1. `find /data -name '*.dat' | grep ose | grep -v temp`
> 2. `find /data -name ose.dat | grep -v temp`
> 3. `grep -v "temp" $(find /data -name '*ose.dat')`
> 1. `find /data -name '*s.txt' | grep -v net`
> 2. `find /data -name *s.txt | grep -v net`
> 3. `grep -v "temp" $(find /data -name '*s.txt')`
> 4. None of the above.
>
> > ## Solution
> > The correct answer is 1. Putting the match expression in quotes prevents the shell
> > expanding it, so it gets passed to the `find` command.
> >
> > Option 2 is incorrect because the shell expands `*s.txt` instead of passing the wildcard
> > expression to `find`.
> >
> > Option 3 is incorrect because it searches the contents of the files for lines which
> > do not match "temp", rather than searching the file names.
> {: .solution}
{: .challenge}

> ## Tracking a Species
Expand All @@ -544,15 +568,14 @@ about them."
> ~~~
> {: .source}
>
> She wants to write a shell script that takes a directory and a species
> as command-line parameters and return one file called `species.txt`
> containing a list of dates and the number of that species seen on that date,
> such as this file for rabbits:
> She wants to write a shell script that takes a species as the first command-line argument
> and a directory as the second argument. The script should return one file called `species.txt`
> containing a list of dates and the number of that species seen on each date.
> For example using the data shown above, `rabbits.txt` would contain:
>
> ~~~
> 2013-11-05,22
> 2013-11-06,19
> 2013-11-07,18
> ~~~
> {: .source}
>
Expand All @@ -571,6 +594,23 @@ about them."
>
> Hint: use `man grep` to look for how to grep text recursively in a directory
> and `man cut` to select more than one field in a line.
>
> An example of such a file is provided in `data-shell/data/animal-counts/animals.txt`
>
> > ## Solution
> >
> > ```
> > grep -w $1 -r $2 | cut -d : -f 2 | cut -d , -f 1,3 > $1.txt
> > ```
> > {: .source}
> >
> > You would call the script above like this:
> >
> > ```
> > $ bash count-species.sh bear .
> > ```
> > {: .bash}
> {: .solution}
{: .challenge}

> ## Little Women
Expand All @@ -579,13 +619,42 @@ about them."
> Louisa May Alcott, are in an argument. Of the four sisters in the
> book, Jo, Meg, Beth, and Amy, your friend thinks that Jo was the
> most mentioned. You, however, are certain it was Amy. Luckily, you
> have a file `LittleWomen.txt` containing the full text of the novel.
> have a file `LittleWomen.txt` containing the full text of the novel
> (`data-shell/writing/data/LittleWomen.txt`).
> Using a `for` loop, how would you tabulate the number of times each
> of the four sisters is mentioned?
>
> Hint: one solution might employ
> the commands `grep` and `wc` and a `|`, while another might utilize
> `grep` options.
> There is often more than one way to solve a programming task, so a
> particular solution is usually chosen based on a combination of
> yielding the correct result, elegance, readability, and speed.
>
> > ## Solutions
> > ```
> > for sis in Jo Meg Beth Amy
> > do
> > echo $sis:
> > grep -ow $sis littlewomen.txt | wc -l
> > done
> > ```
> > {: .source}
> >
> > Alternative, slightly inferior solution:
> > ```
> > for sis in Jo Meg Beth Amy
> > do
> > echo $sis:
> > grep -ocw $sis LittleWomen.txt
> > done
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say let's leave out the inferior solution altogether. Any advantage to keeping it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only that the question suggests two different ways to achieve the outcome. I don't mind removing the alternative solution, so long as we also remove the hint which suggests it.

Or I could add a short note explaining that there is often more than one way to complete a programming task.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @gcapes - I'd suggest keeping the hint and adding the note.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

> > ```
> > {: .source}
> >
> > This solution is inferior because `grep -c` only reports the number of lines matched.
> > The total number of matches reported by this method will be lower if there is more
> > than one match per line.
> {: .solution}
{: .challenge}

> ## Finding Files With Different Properties
Expand All @@ -600,10 +669,12 @@ about them."
>
> Hint 2: The value for `-mtime` will need to be negative---why?
>
> Solution: Assuming that Nelle’s home is our working directory we type:
>
> ~~~
> $ find ./ -type f -mtime -1 -user ahmed
> ~~~
> {: .bash}
> > ## Solution
> > Assuming that Nelle’s home is our working directory we type:
> >
> > ~~~
> > $ find ./ -type f -mtime -1 -user ahmed
> > ~~~
> > {: .bash}
> {: .solution}
{: .challenge}
8 changes: 8 additions & 0 deletions data-shell/data/animal-counts/animals.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
2012-11-05,deer,5
2012-11-05,rabbit,22
2012-11-05,raccoon,7
2012-11-06,rabbit,19
2012-11-06,deer,2
2012-11-06,fox,4
2012-11-07,rabbit,16
2012-11-07,bear,1