diff --git a/examples/Simple.hs b/examples/Simple.hs new file mode 100644 index 0000000..c115693 --- /dev/null +++ b/examples/Simple.hs @@ -0,0 +1,70 @@ +import Control.Monad +import qualified Data.ByteString.Char8 as S +import System.FilePath +import System.FilePath.Find +import System.FilePath.Manip +import Text.Regex.Posix ((=~)) + + + +-- Get a list of all symlinks. + +getDanglingLinks :: FilePath -> IO [FilePath] + +getDanglingLinks = find always (fileType ==? SymbolicLink &&? + followStatus ==? Nothing) + + + +-- Rename all ".cpp" files to ".C". + +renameCppToC :: FilePath -> IO () + +renameCppToC path = find always (extension ==? ".cpp") path >>= + mapM_ (renameWith (replaceExtension ".C")) + + + +-- A recursion control predicate that will avoid recursing into +-- directories commonly used by revision control tools. + +noRCS :: RecursionPredicate + +noRCS = (`elem` ["_darcs","SCCS","CVS",".svn",".hg",".git"]) `liftM` fileName + +cSources :: FilePath -> IO [FilePath] + +cSources = find noRCS (extension ==? ".c" ||? extension ==? ".h") + + + +-- Replace all uses of "monkey" with "simian", saving the original copy +-- of the file with a ".bak" extension: + +monkeyAround :: FilePath -> IO () + +monkeyAround = modifyWithBackup (<.> "bak") (unwords . map reMonkey . words) + where reMonkey x = if x == "monkey" then "simian" else x + + + +-- Given a simple grep, it's easy to construct a recursive grep. + +grep :: (Int -> S.ByteString -> a) -> String -> S.ByteString -> [a] + +grep f pat s = consider 0 (S.lines s) + where consider _ [] = [] + consider n (l:ls) | S.null l = consider (n+1) ls + consider n (l:ls) | l =~ pat = (f n l):ls' + | otherwise = ls' + where ls' = consider (n+1) ls + +grepFile :: (Int -> S.ByteString -> a) -> String -> FilePath -> IO [a] + +grepFile f pat name = grep f pat `liftM` S.readFile name + +recGrep :: String -> FilePath -> IO [(FilePath, Int, S.ByteString)] + +recGrep pat top = find always (fileType ==? RegularFile) top >>= + mapM ((,,) >>= flip grepFile pat) >>= + return . concat