You tell sed to look for the combination '' ', and then .* (Anything), and then as part of your replacement you return the characters ] .
The only problem is that sed usually "thinks" that ] char is part of the definition of a character class, so you need to avoid it. Try
echo "ab [c] d" | sed 's/\] .*$/\] XYZ/' ab [c] XYZ
Note that due to the lack of opening [ char to mean char -class def, you can get away with
echo "ab [c] d" | sed 's/] .*$/] XYZ/' ab [c] XYZ
Edit
To correct only the 4th word,
echo "ab [c] de" | sed 's/\] [^ ][^ ]*/\] XYZ/' ab [c] XYZ e
Adding above [^ ][^ ]/ says "any-char -that-is-not-a-space" followed by any number "any-w983> -that-is-not-a-space", therefore, when the interlocutor finds the next place, a coincidence of stops occurs.
final editing
echo "penguin bird [lives in Antarctica] The penguin lives in cold places. wold dog [lives in Antarctica with penguins] The wolf likes to eat penguins." \ | sed 's/\] The penguin \(.*$\)/] The animal \1/'
and when you use gnu sed you don't need to go beyond (... ).
echo "penguin bird [lives in Antarctica] The penguin lives in cold places. wold dog [lives in Antarctica with penguins] The wolf likes to eat penguins." \ | sed 's/\] The penguin (*$)/] The animal \1/'
Output
penguin bird [lives in Antarctica] The animal lives in cold places. wolf dog [lives in Antarctica with penguins] The wolf likes to eat penguins.
Depending on the version of sed you are using. There is a pretty big difference between sed for AIX , vs solaris , VS, which GNU seds usually reside on lunix.
If you have other questions about using sed, it is usually helpful to include the output of sed --version or sed -V . If there is no response from these commands, try what sed . Else includes the OS name for uname .
Ihth