diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+1.4.5
+
+* Add `grepText`, `uniq`, `nub`, `sort` to `Turtle.Prelude`
+* Increase upper bound on `unix-compat`
+
 1.4.4
 
 * Fix small mistake in tutorial
diff --git a/src/Turtle/Prelude.hs b/src/Turtle/Prelude.hs
--- a/src/Turtle/Prelude.hs
+++ b/src/Turtle/Prelude.hs
@@ -3,6 +3,7 @@
 {-# LANGUAGE OverloadedStrings          #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE RankNTypes                 #-}
+{-# LANGUAGE TupleSections              #-}
 
 -- | This module provides a large suite of utilities that resemble Unix
 --  utilities.
@@ -171,6 +172,7 @@
     , lstree
     , cat
     , grep
+    , grepText
     , sed
     , sedPrefix
     , sedSuffix
@@ -190,6 +192,14 @@
     , cache
     , parallel
     , single
+    , uniq
+    , uniqOn
+    , uniqBy
+    , nub
+    , nubOn
+    , sort
+    , sortOn
+    , sortBy
 
     -- * Folds
     , countChars
@@ -279,17 +289,20 @@
 import qualified Control.Concurrent.STM as STM
 import qualified Control.Concurrent.STM.TQueue as TQueue
 import Control.Exception (Exception, bracket, bracket_, finally, mask, throwIO)
-import Control.Foldl (Fold, FoldM(..), genericLength, handles, list, premap)
+import Control.Foldl (Fold(..), FoldM(..), genericLength, handles, list, premap)
 import qualified Control.Foldl
 import qualified Control.Foldl.Text
-import Control.Monad (guard, liftM, msum, when, unless, (>=>))
+import Control.Monad (guard, liftM, msum, when, unless, (>=>), mfilter)
 import Control.Monad.IO.Class (MonadIO(..))
 import Control.Monad.Managed (MonadManaged(..), managed, managed_, runManaged)
 #ifdef mingw32_HOST_OS
 import Data.Bits ((.&.))
 #endif
 import Data.IORef (newIORef, readIORef, writeIORef)
+import qualified Data.List as List
 import Data.Monoid ((<>))
+import Data.Ord (comparing)
+import qualified Data.Set as Set
 import Data.Text (Text, pack, unpack)
 import Data.Time (NominalDiffTime, UTCTime, getCurrentTime)
 import Data.Time.Clock.POSIX (POSIXTime)
@@ -1513,13 +1526,17 @@
 cat :: [Shell a] -> Shell a
 cat = msum
 
+grepWith :: (b -> Text) -> Pattern a -> Shell b -> Shell b
+grepWith f pattern = mfilter (not . null . match pattern . f)
+
 -- | Keep all lines that match the given `Pattern`
 grep :: Pattern a -> Shell Line -> Shell Line
-grep pattern s = do
-    line <- s
-    _:_ <- return (match pattern (lineToText line))
-    return line
+grep = grepWith lineToText
 
+-- | Keep every `Text` element that matches the given `Pattern`
+grepText :: Pattern a -> Shell Text -> Shell Text
+grepText = grepWith id
+
 {-| Replace all occurrences of a `Pattern` with its `Text` result
 
     `sed` performs substitution on a line-by-line basis, meaning that
@@ -1981,3 +1998,84 @@
         _   -> do
             let msg = format ("single: expected 1 line of input but there were "%d%" lines of input") (length as)
             die msg
+
+-- | Filter adjacent duplicate elements:
+--
+-- >>> view (uniq (select [1,1,2,1,3]))
+-- 1
+-- 2
+-- 1
+-- 3
+uniq :: Eq a => Shell a -> Shell a
+uniq = uniqOn id
+
+-- | Filter adjacent duplicates determined after applying the function to the element:
+--
+-- >>> view (uniqOn fst (select [(1,'a'),(1,'b'),(2,'c'),(1,'d'),(3,'e')]))
+-- (1,'a')
+-- (2,'c')
+-- (1,'d')
+-- (3,'e')
+uniqOn :: Eq b => (a -> b) -> Shell a -> Shell a
+uniqOn f = uniqBy (\a a' -> f a == f a')
+
+-- | Filter adjacent duplicate elements determined via the given function:
+--
+-- >>> view (uniqBy (==) (select [1,1,2,1,3]))
+-- 1
+-- 2
+-- 1
+-- 3
+uniqBy :: (a -> a -> Bool) -> Shell a -> Shell a
+uniqBy cmp s = Shell $ \(FoldM step begin done) -> do
+  let step' (x, Just a') a | cmp a a' = return (x, Just a)
+      step' (x, _) a = (, Just a) <$> step x a
+      begin' = (, Nothing) <$> begin
+      done' (x, _) = done x
+  foldIO s (FoldM step' begin' done')
+
+-- | Return a new `Shell` that discards duplicates from the input `Shell`:
+--
+-- >>> view (nub (select [1, 1, 2, 3, 3, 4, 3]))
+-- 1
+-- 2
+-- 3
+-- 4
+nub :: Ord a => Shell a -> Shell a
+nub = nubOn id
+
+-- | Return a new `Shell` that discards duplicates determined via the given function from the input `Shell`:
+--
+-- >>> view (nubOn id (select [1, 1, 2, 3, 3, 4, 3]))
+-- 1
+-- 2
+-- 3
+-- 4
+nubOn :: Ord b => (a -> b) -> Shell a -> Shell a
+nubOn f s = Shell $ \(FoldM step begin done) -> do
+  let step' (x, bs) a | Set.member (f a) bs = return (x, bs)
+                      | otherwise = (, Set.insert (f a) bs) <$> step x a
+      begin' = (, Set.empty) <$> begin
+      done' (x, _) = done x
+  foldIO s (FoldM step' begin' done')
+
+-- | Return a list of the sorted elements of the given `Shell`, keeping duplicates:
+--
+-- >>> sort (select [1,4,2,3,3,7])
+-- [1,2,3,3,4,7]
+sort :: (Functor io, MonadIO io, Ord a) => Shell a -> io [a]
+sort = sortOn id
+
+-- | Return a list of the elements of the given `Shell`, sorted after applying the given function and keeping duplicates:
+--
+-- >>> sortOn id (select [1,4,2,3,3,7])
+-- [1,2,3,3,4,7]
+sortOn :: (Functor io, MonadIO io, Ord b) => (a -> b) -> Shell a -> io [a]
+sortOn f = sortBy (comparing f)
+
+-- | Return a list of the elements of the given `Shell`, sortesd by the given function and keeping duplicates:
+--
+-- >>> sortBy (comparing fst) (select [(1,'a'),(4,'b'),(2,'c'),(3,'d'),(3,'e'),(7,'f')])
+-- [(1,'a'),(2,'c'),(3,'d'),(3,'e'),(4,'b'),(7,'f')]
+sortBy :: (Functor io, MonadIO io) => (a -> a -> Ordering) -> Shell a -> io [a]
+sortBy f s = List.sortBy f <$> fold s list
diff --git a/turtle.cabal b/turtle.cabal
--- a/turtle.cabal
+++ b/turtle.cabal
@@ -1,5 +1,5 @@
 Name: turtle
-Version: 1.4.4
+Version: 1.4.5
 Cabal-Version: >=1.10
 Build-Type: Simple
 License: BSD3
@@ -54,6 +54,7 @@
         async                >= 2.0.0.0 && < 2.2 ,
         bytestring           >= 0.9.1.8 && < 0.11,
         clock                >= 0.4.1.2 && < 0.8 ,
+        containers           >= 0.5.0.0 && < 0.6 ,
         directory            >= 1.0.7   && < 1.4 ,
         foldl                >= 1.1     && < 1.4 ,
         hostname                           < 1.1 ,
@@ -69,7 +70,7 @@
         transformers         >= 0.2.0.0 && < 0.6 ,
         optparse-applicative >= 0.13    && < 0.15,
         optional-args        >= 1.0     && < 2.0 ,
-        unix-compat          >= 0.4     && < 0.5
+        unix-compat          >= 0.4     && < 0.6
     if os(windows)
         Build-Depends: Win32 >= 2.2.0.1 && < 2.4
     else
