\documentclass{beamer}
% \documentclass[handout]{beamer}

\usetheme{dcc}

\usepackage[utf8]{inputenc}
\usepackage[american]{babel}
\usepackage{url}

\newcommand{\ie}{i.\,e.}
\newcommand{\Ie}{I.\,e.}
\newcommand{\eg}{e.\,g.}
\newcommand{\Eg}{E.\,g.}

\title{Mineração de Dados Aplicada}
\subtitle{\texttt{sed}'s substitution}

\author{Loïc Cerf}

\date{April 9th 2025}

\institute
{
  \scriptsize
  DCC -- ICEx -- UFMG
  \bigskip\\
  \includegraphics[width=.334113288\linewidth]{images/dcc}\hfill\includegraphics[width=.5\linewidth]{images/ufmg}
}

\subject{sed}

\keywords{sed}

\hypersetup{pdfpagemode=FullScreen}

\AtBeginSection[]
{
  \begin{frame}<beamer>
    \frametitle{Outline}
    \tableofcontents[currentsection]
  \end{frame}
}

\begin{document}

\begin{frame}[plain]
  \titlepage
\end{frame}

\begin{frame}
  \frametitle{Outline for the next sessions}
  \begin{description}
  \item[Today] \texttt{sed}'s substitution;
  \item[14/04] \texttt{awk}'s basics;
  \item[16/04] \texttt{awk}'s array and string processing;
  \item[23/04] A few words about efficiency.
  % \item[24/09] \alert<2>{Oral presentation of your data}.
  \end{description}

  \vfill

  \uncover<2>{Date for the exam on the POSIX text-processing
    commands?}
\end{frame}

\begin{frame}
  \frametitle{Outline for this session}
  % \frametitle{Outline}
  \tableofcontents
\end{frame}

\section{Correction of last session exercise}

\begin{frame}
  \frametitle{Repeated user names}
  \begin{alertblock}{Exercise for today}
    In \texttt{retweets.txt}, what users have names that only differ
    by their cases?
  \end{alertblock}

  \vfill
  \pause

  \begin{exampleblock}{Repeated user names\uncover<3>{ (all
        versions)}}
    \texttt{tr -s ' ' '\textbackslash t' < retweets.txt | cut -f 5 | sort -u}\\
    \texttt{| sort -f | uniq -i\only<2,4>{d}\only<3>{ --all-repeated=separate}}
  \end{exampleblock}

  \vfill
  \pause

  \uncover<4>{\begin{exampleblock}{Without \texttt{cut} (whole lines
        are output)}
      \texttt{sort -uk 4 retweets.txt | sort -fk 4 | uniq -idf 3}
    \end{exampleblock}
  }
\end{frame}

\section{Non-interactive editing}

\begin{frame}
  \frametitle{Adding transformational capabilities}
  \texttt{grep} only \emph{selects} lines based on a
  regexp. \texttt{sed} additionally allows to \emph{transform} those
  lines.

  \vfill
  \pause

  \texttt{sed} is Turing-complete. A complex \texttt{sed} script is
  quite hard to read, unless you are a computer.
\end{frame}

\begin{frame}
  \frametitle{Learning \texttt{sed}}
  \begin{enumerate}
  \item The following slides;
  \item Tutorials on the Web;
  \item '\texttt{info sed}'.
  \end{enumerate}

  \vfill
  \pause

  And cheat sheets on the Web...
\end{frame}

\begin{frame}
  \frametitle{A few options}
  \begin{itemize}
  \item Generalizing \texttt{grep}, the -e option introduces a new
    ``script'' and -f a ``script file''.
  \item By default, every line that is read is output (edited or
    not). The -n option avoids that.
  \item \texttt{sed} edits ``in place'' with the -i option.
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{\texttt{sed}'s program structure}
  A \texttt{sed} script is a sequence of condition-action
  statements. If the condition selects a line, the related action is
  executed on it.

  \vfill
  \pause

  The most useful conditions are:
  \begin{itemize}[<+->]
  \item a line number or \texttt{\$} for the last line, \eg,
    \texttt{8};
  \item a regexp (between '\texttt{/}'), \eg, \texttt{/b.*a/};
  \item ranges of lines whose boundaries are specified through line
    numbers or regexps, \eg, \texttt{8,\$} or \texttt{1,/banana/};
  \item the negation of a condition by appending \texttt{!}, \eg,
    \texttt{6,/[xyz]/!}.
  \end{itemize}

  \uncover<6>{\alert{If no condition is given, every line is
      selected.}}
\end{frame}

\begin{frame}
  \frametitle{\texttt{sed}'s commands}
  \texttt{sed}'s commands are one letter long:
  \begin{itemize}[<+->]
  \item \texttt{p} prints the current line;
  \item \texttt{d} deletes the current line;
  \item \texttt{i} inserts a line (before the current line);
  \item \texttt{a} appends a line (after the current line);
  \item ...
  \item \alert{\texttt{s} substitutes part(s) of the current line.}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Substituting with \texttt{sed}'s \texttt{s} command}
  The usual syntax is \texttt{s/regexp/replacement text/\{flags\}} but
  any character can replace the \texttt{/} delimiter.

  \vfill
  \pause

  Like \texttt{grep}, \texttt{sed} matches the \emph{largest} string
  satisfying the \texttt{regexp}.  In the \texttt{replacement text},
  \texttt{\&} stands for the whole match and \texttt{\textbackslash n}
  for the string matching the part of the regexp between the
  \texttt{n}$^{\text{th}}$ \texttt{\textbackslash( \textbackslash)}.

  \vfill
  \pause

  The most useful \texttt{flags} are a number N to transform the
  N$^\text{th}$ match per line (the first by default), \texttt{g} to
  transform all matches and \texttt{p}, in conjunction with the -n
  option, to only print the transformed lines.
\end{frame}

\begin{frame}
  \frametitle{Getting the data}
  \texttt{wget --no-check-certificate -O - \textbackslash{}\\
    \url{dcc.ufmg.br/~lcerf/data.tar.xz} | tar -xJ}
\end{frame}

\begin{frame}
  \frametitle{Exercises}
  \begin{exampleblock}{Exercises}
    \begin{enumerate}
    \item In \texttt{teams.txt}, replace
      ``\texttt{Atlético}'' with ``\texttt{Atl.}''.
    \item In \texttt{teams.txt}, place an exclamation mark at the
      beginning of the lines containing ``\texttt{Atlético}''.
    \item Execute the script \texttt{teams.sed} on
      \texttt{retweets.txt}.
    \item If ``\texttt{s:200:Atlético-MG:}'' would be the first line
      of \texttt{teams.sed}, this script would undesirably edit some
      retweet numbers and some user names that include the sequence of
      digits ``\texttt{200}''. Explain how the actual script avoids
      those issues.
    \item How to obtain \texttt{teams.sed} from \texttt{teams.txt}?
      Notice that underscores replace the spaces in the team names.
    \end{enumerate}
  \end{exampleblock}
\end{frame}

\begin{frame}
  \frametitle{Turning \texttt{teams.txt} into \texttt{teams.sed}}
  \begin{tabular}{rl}
    From: & \texttt{213~~~~Grêmio Prudente}\\
    To: & \texttt{s:\textbackslash([0-9] \textbackslash)213
      :\textbackslash1Grêmio\_Prudente :}
  \end{tabular}

  \vfill
  \pause

  \begin{exampleblock}{With one barely readable substitution}
    \texttt{tr ' ' \_ < teams.txt | sed}\\
    \texttt{'s/\textbackslash(.*\textbackslash)\_\_\_\_\textbackslash(.*\textbackslash)/s:\textbackslash\textbackslash([0-9]
      \textbackslash\textbackslash)\textbackslash1 :\textbackslash\textbackslash1\textbackslash2
      :/' > teams.sed}
  \end{exampleblock}

  \vfill
  \pause

  \begin{exampleblock}{With three substitutions}
    \texttt{tr ' ' \_ < teams.txt | sed -e 's/\^{ }/s:\textbackslash\textbackslash([0-9] \textbackslash\textbackslash)/'}\\
    \texttt{-e 's/\_\_\_\_/ :\textbackslash\textbackslash1/' -e 's/\$/ :/' > teams.sed}
  \end{exampleblock}
\end{frame}

% \begin{frame}
%   \frametitle{Reading the Folha de São Paulo}
%   \begin{exampleblock}{Reading an article (URL in argument)}
%     \texttt{\#!/bin/sh}\\
%     ~\\
%     \texttt{wget -qO - \$1 | sed -n
%       's:<p>\textbackslash(.*\textbackslash)</p>:\textbackslash
%       1\textbackslash n:p'}\\
%     \texttt{| sed -e '1s/\^{ } *//' -e '/\^{ }[[:blank:]]/d'}\\
%     \texttt{-e 's/<[\^{ }>]*>//g' -e 's/\&nbsp;/ /g'}\\
%     \texttt{-e 's/\&\#8230;/…/g' | fold -sw 66 | less}
%   \end{exampleblock}

%   \vfill

%   The last two substitutions replace special HTML characters.  There
%   are more.
% \end{frame}

\section{Exercises for next Monday}

\begin{frame}
  \frametitle{Exercises}
  \begin{alertblock}{Exercises for next Monday}
    Given a list of keywords and a text, ignore the letter case and
    use the commands presented so far to:
    \begin{enumerate}
    \item list each keyword occurring in the text;
    \item count the occurrences of each keyword in the text.
    \end{enumerate}
    Both problems can be solved \emph{with} or, sorting all the words
    in the text, \emph{without} grep.  Will you find both ways?
  \end{alertblock}
\end{frame}

\section*{}

\begin{frame}
  \frametitle{License}
  \begin{block}{\copyright 2012--2025 Loïc Cerf}
    \includegraphics[height=1.5ex]{img/licenses/cc-by-sa}\hskip1pt
    These slides are licensed under the Creative Commons
    Attribution-ShareAlike 4.0 International License.
  \end{block}
\end{frame}

\end{document}