CS 279 - Week 12 Lecture 1 - 2022-11-07

TODAY WE WILL
*   announcements/reminders
*   intro to sed
*   [did not get to] [if time] a little more you can do with
    Bash command history
*   prep for next class

*   example solutions for Homeworks 4-7 *should* be reachable
    for Exam 2 study purposes

*   Exam 2 - this Wednesday - November 9

    *   IF you'd like the Exam 2 BONUS --
        submit that scan of your HANDWRITTEN Exam 2 Review Sheet
        by 9:00 am on Wednesday

=====
intro to sed
=====
*   stream editor...!

*   sed applies a fixed set of editing changes
    to a file or sequence of files --
    allows you to modify streams of test on the fly;

*   written in 1973 or 1974 by Lee McMahon

*   basic work cycle:
    1. read an entire line from standard input into its
       pattern buffer

    2. modify the pattern buffer according to the supplied
       commands

    3. print the resulting pattern buffer to standard out

    *   expects BREs unless you use option -E

*   basic syntax:

    sed -e desired_script file1 file2 ...
    sed -f desired_script_file file1 file2 ...

    desired_script: script of editing commands
    file1 file2 ... : a list of files to be edited
    desired_script_file: a file with the sed script commands

*   one of the sed commands that can be in a sed script
    is s, for substitute

    s/pattern_to_subst/what_to_subst/

    this substitutes what_to_subst for the FIRST instance
    matching pattern_to_subst in each line of the files in the
    given file list

*   SO: a first example:

    sed -e 's/UNIX/Linux/' unix-stuff.txt

    *   substitutes Linux for the first UNIX in each line of unix-stuff.txt,
        and outputs the result to the screen

*   there can be commands at the END of the sed script --
    a popular one is g, global, saying you want ALL of that
    matching instances in each line to have the specified change
    made

    sed -e 's/UNIX/Linux/g' unix-stuff.txt

    *   substitutes Linux for every UNIX in each line of unix-stuff.txt,
        and outputs the result to the screen

    sed -e 's/#.*//' clicker-rematch.sh

=====
selectors in sed commands
=====
*   you can specify WHICH lines in a file to edit;

    you use a selector for that.

*   selector: an "address" or pair of "addresses"
    that specify the lines to be potentially affected

    "address": a line number or a BRE

    (and the RE is usually in // although it CAN be delimited by
    other characters as well)

*   a command is executed only if it is selected/if its selector
    is satisfied

*   a few examples:

    sed -e '3,5s/#.*//' clicker-rematch.sh

    ...should replace the comments with empty just on lines 3-5 in
       unix-stuff.txt

    sed -e '/^if/,/fi/s/\(.*\)/# MOO\1/' clicker-rematch.sh

    ...just puts # MOO in front of each line in a top-level if
       within clicker-rematch.sh

    a few more patterns:

    /walrus/,/oyster/    #  selects groups of lines that start with
                         #     a line containing walrus and ends with
			 #     one containing oyster

    3,/oyster/           # selects line 3 up to and including the
                         #     next line containing oyster
			 #     (or all the rest of the lines if none
			 #     have oyster...)

*   if you give just one selector, lines matching that will be
    affected

    # substite foo with bar ONLY
    #    for lines containing baz

    sed -e '/baz/s/foo/bar/g' foodiebar.txt

*   you can put ! at the end of selector to
    say select the lines that DON'T match this --

    # substite foo with bar ONLY
    #    for lines NOT containing baz

    sed -e '/baz/!s/foo/bar/g' foodiebar.txt

    # hey, you can have a blank between the selector and the command!

    sed -e '/baz/! s/foo/bar/g' foodiebar.txt

=====
sed flags
=====
*   more options you can add to the end of the script/command
    of a sed statement:

    *   we've seen g:
        sed -e 's/foo/bar/g' *.txt   # all the foo in each line become bar

    *   put a number n at the end, just the nth instance is substituted

        sed -e 's/foo/bar/2' *.txt   # the 2nd foo in each line become bar

*   there IS a delete command, also:  d

    # should delete blank lines in clicker-rematch.sh

    sed -e '/^$/d' clicker-rematch.sh

    sed -e 's/#.*//' clicker-rematch.sh | sed -e '/^$/d'