# [Zsh] + coreutils, <sup><s>406</s></sup> 375 bytes

<!-- language-all: lang-sh -->

    g()ls -t<>"She$d the $1 to catch the $2,"
    set bird spider \ swallow iggled\ 
    <<Z
    ${b=There was an old lady who${d=$3ed} a }fly.${5=
    I don't know why she$d that fly,
    Perhaps she'll die.
    
    $b}$2,
    That wr$4and $4and j$4inside her.
    `g $2 fly`$5$1,
    How absurd${6= to$3 a }$1.
    `g $@`$5cat,
    Imagine that$6cat.
    `g cat $1`$5dog,
    What a hog$6dog.
    `g dog cat`$5horse,
    She died of course.

[Try it online!][TIO-kqf8hx3u]

[Zsh]: https://www.zsh.org/
[TIO-kqf8hx3u]: https://tio.run/##5VTBTuswELz7K1ZoJUAKkfqAnlrgCDckkJ5UccDNOnHAjavYKOoL/fa@dRyghSI4IRCXyPJOdmdG6/nn9CojwL3ZvVezORzQvsikP0nz0WgirrWqFTTSgazAGgIjaQGNtuAaaYxtFIGE3CxScQFkq10P95VtGLEAp9UaymvpAzARl6rWcu5CfdcYoFKl4pOD3LwkVSeM5mZNXRaFCfcVwdrxrj@XlWM0cONUXL3iovpW4C2w2kx3dx29r9AxLWtKxDkPkFP3UFOg0df76jbK4X6T8JMf30wej@RBM1mUlYodN/RxeZu8LOJe@EaXfrAPZItE/A2dJGhbbLrAxW0uUMS9sO3M/A1uaVs7FVnxbwQ2h8w@8F0qJqJdFXv7xsGBH53sMAQjYRxsksU/yY5wykfVvZybZ9djMtyACNmG7XT8LjNsaYyHipZMbBnyDdvj8VYb8EP5OF0yr6fQwqMQUvF7h0frKXVbsIDQ6BaPcbAeENgOx6wUDwMdHEToGcPePDUcds@L62FDcMCYV2uIw271GBF2jVEMed/71UQsH71SkBaCyjyH9JTdG@Hp6j8 "Zsh – Try It Online"

Tricks:
- the `g` function creates the line as a file and then `ls` lists the files in the current directory in order of creation (`-t`), to avoid having to repeat the previous lines every time.
  - I used `<>` (which creates the file before the command is executed) instead of `>...;` because using multiple commands in a function  requires `{}` around them
- `set bird ...` assigns the words to `$1`, `$2`, etc.
- `\ swallow` includes a space at the start of without needing to use quotes
- `<<Z` starts a heredoc which is effectively a long interpolated string
- `${b=There...}` is a shorthand form setting `b` to that string and substituting its value in
- Indexed variables like `$1`, `$2`, etc. can be substituted without a space afterwards (rather than being interpreted as a variable called `5dog`, for example), so we prefer them as it allows us to include the space inside the assignment to avoid repeating it
- `g $@`: since we set `$1` and `$2` to `bird` and `spider` respectively, we can pass all the numbered variables to `g` in one go with `$@` instead of `g $1 $2` (it ignores the extra ones, `$3` etc.)