16
16. ファイルをN分割する
自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.
16.hs
import System.Environment import Control.Monad main = do args <- getArgs let num = (read :: String -> Int) $ head args let filename = args !! 1 body <- getContents let l = lines body let a = div (length l) num + mod (length l) num let b = splitAt' a l mapM_ (\x -> writeFile (filename ++ (show x) ++ ".txt") $ unlines (b !! (x - 1))) [1..num] splitAt' n xs | length xs <= n = [xs] | otherwise = x :(splitAt' n y) where (x, y) = splitAt n xs
結構、プログラムが長くて、読みにくくなってしまった。行をn個に分割する関数を定義したら、良かったかもしれない。
15
15. 末尾のN行を出力
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.
> tail -n 10
15.hs
import System.Environment main = do num <- getArgs >>= return . (read :: String -> Int) . head body <- getContents putStrLn $ unlines $ reverse $ take num $ reverse $ lines body
14.hsを流用したが、
このプログラムだと、入力された文字列を瞬間的に全部保持する!?
13
13. col1.txtとcol2.txtをマージ
12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.
pasteコマンドなかったため未実施。たぶん下記の通り。
>paste col1.txt col2.txt
13.hs
import System.Environment import System.IO.UTF8 as I8 import Data.List main = do files <- getArgs body <- mapM (\x -> I8.readFile x >>= return . lines) files I8.writeFile "out.txt" $ unlines $ map unwords $ transpose body
実行は省略。文字列の出力処理に悩む。
12
12. 1列目をcol1.txtに,2列目をcol2.txtに保存
各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.
> cut -f 1 hightemp.txt > col1.txt > cut -f 2 hightemp.txt > col2.txt
12.hs
import System.IO as I import System.Environment import System.IO.UTF8 as I8 main = do file <- getArgs >>= return . head body <- I8.readFile file let wss = map words $ lines body I.writeFile "col1.txt" $ unlines $ map head wss I.writeFile "col2.txt" $ unlines $ map (last . take 2) wss
実行結果は省略。
11
11. タブをスペースに置換
タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.
>sed "s/\t/ /g" hightemp.txt >tr "\t" " " < hightemp.txt
expandはなかったためやめる。
11.hs
import System.IO.UTF8 as I8 import System.Environment import Prelude as P main = do filename <- getArgs >>= return . head body <- I8.readFile filename P.putStrLn $ unlines $ map (map f) $ lines body where f '\t' = ' ' f x = x
読み込みはutf8-stringで、出力がPreludeという組み合わせで
うまくいくのがよくわからないが、ひとまずこれで。
10
2章はUnixのコマンドの練習のようだけれども、
Haskellを書きたいので、同様のプログラムも作成していく。と思っていたら、よく読んでみたら、プログラム書く演習だった。
10. 行数のカウント
行数をカウントせよ.確認にはwcコマンドを用いよ.
10.hs
import System.Environment import qualified System.IO.UTF8 as I8 main = do file <- getArgs body <- I8.readFile $ head file print $ length $ lines body
>wc -l hightemp.txt 24 hightemp.txt >runghc 10.hs hightemp.txt 24
utf8-string-0.3.8使用。バージョン1では、System.IO.UTF8をGHCで対応したから削除したとのことだったが、つかっているghcはHaskell Platform 2014を使っているため。