Skip to content

Instantly share code, notes, and snippets.

@igrep
Created June 20, 2017 03:54
Show Gist options
  • Select an option

  • Save igrep/8a1c2cde03de4ac0d9e7dc18b52e5051 to your computer and use it in GitHub Desktop.

Select an option

Save igrep/8a1c2cde03de4ac0d9e7dc18b52e5051 to your computer and use it in GitHub Desktop.
Haskell scriptingたのしー!
#!/bin/env stack
{- stack --resolver=lts-8.19
runghc
--package=attoparsec
--package=bytestring
--package=unordered-containers
--package=filepath
-}
{-
duコマンドが出力した下記のような形式のファイルから、拡張子別のファイルサイズの合計を計算する
12345 /path/to/file.txt
123 /path/to/another/file.jar
...
-}
{-# LANGUAGE OverloadedStrings #-}
import qualified Control.Arrow as A
import Control.Arrow ((>>>))
import qualified Data.Attoparsec.ByteString.Char8 as ABS
import qualified Data.Attoparsec.ByteString.Lazy as ABSL
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BSL
import Data.Either (partitionEithers)
import Data.Function ((&))
import qualified Data.HashMap.Strict as M
import Data.List (sortBy)
import Data.Ord (comparing)
import System.FilePath (takeExtension)
type Size = Int
type Extension = String
parser :: ABS.Parser (Extension, Size)
parser =
flip (,)
<$> ABS.decimal
<*> (takeExtension . BS.unpack <$> ABSL.takeByteString)
main :: IO ()
main = do
contents <- BSL.getContents
let (errs, result) =
BSL.lines contents -- 各行を
& map (ABSL.eitherResult . ABSL.parse parser) -- 拡張子とファイルサイズに分けて
& partitionEithers -- エラーと正常な結果に分けて
& A.second -- 正常な結果から
( M.fromListWith (+) -- 拡張子毎のファイルサイズの合計を計算し
>>> M.toList
>>> sortBy (comparing snd) -- ファイルサイズ順に並び替える
)
putStrLn $ "Errors: " ++ show errs
mapM_ print result
@igrep
Copy link
Copy Markdown
Author

igrep commented Jun 20, 2017

特筆すべき点はありませんが今仕事の野暮用で書いていて楽しかったので。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment