hwk: Simple Haskell-based awk-like tool

[ development, mit, program ] [ Propose Tags ]

A simple Haskell-based alternative to awk/sed. It uses Hint to apply the function given on the commandline to standard input and outputs the result.

[Skip to Readme]


Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Versions [RSS] 0.2.0, 0.3, 0.4, 0.5, 0.6
Change log ChangeLog.md
Dependencies base (<5), directory (>=, extra, filepath, hint, simple-cmd-args (>=0.1.2) [details]
License MIT
Copyright 2016-2017 Lukas Martinelli, 2020 Jens Petersen
Author Lukas Martinelli
Maintainer Jens Petersen <juhpetersen@gmail.com>
Category Development
Home page https://github.com/juhp/hwk
Source repo head: git clone https://github.com/juhp/hwk.git
Uploaded by JensPetersen at 2020-10-11T16:28:50Z
Distributions Fedora:0.6, LTSHaskell:0.6, NixOS:0.6
Executables hwk
Downloads 568 total (9 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
Last success reported on 2020-10-11 [all 2 reports]

Readme for hwk-0.3

[back to package description]

hwk MIT licensed

hwk was originally written by Lukas Martinelli in 2016-2017: see the original README file.


hwk (pronounced "hawk") is a simple Haskell-based text stream manipulation tool, somewhat similar to tools like awk or sed. hwk applies concisely composed pure functions to a list of strings from stdin. Because Haskell is lazy and has a powerful arsenal of functions, there is no need to invent another DSL. Hopefully this tool will also encourage more people to think functionally.


Change and append a string to each line:

$ seq 0 2 | hwk --line '(++ ".txt") . show . (+1) . int'

or without line-mode: hwk 'map ((++ ".txt") . show . (+1) . int)'.

Sum all negative numbers:

$ seq -100 100 | hwk 'sum . filter (< 0) . ints'

The ints function transforms a list of strings into a list of ints

Factorials in your shell scripts!:

seq 10 12 | hwk --line 'let {fact 0 = 1; fact n = n * fact (n - 1)} in fact . int'

Extract data from a file:

$ cat /etc/passwd | hwk --line 'reverse . filter (/= "x") . take 3 . splitOn ":"' | head -3
0 root
1 bin
2 daemon

(a module defining splitOn from the extra or split library needs to be added to the Hwk.hs config file).

The argument passed to hwk must be a valid Haskell function: a function that takes a list of strings and returns a new list or a single value.

Check where input contains a certain string:

$ cat /etc/passwd | hwk --all 'bool "no" "yes" . isInfixOf "1000"'


hwk uses a Haskell configuration file ~/.config/hwk/Hwk.hs which provides the context for the hint evaluation of the supplied function.

The default configuration Hwk module just sets the Prelude, Data.List, and Data.Char modules to be imported into the hint interpreter.

The first time hwk is run it sets up ~/.config/hwk/Hwk.hs.

You can add other modules to import or define your own functions in ~/.config/hwk/Hwk.hs.

After a hwk version update you may wish/have to update up your Hwk.hs file to take account of new changes: a copy of the latest default Hwk.hs is also put in ~/.config/hwk/ with version suffix.


Either use the install.sh script, or install by cabal-install or stack as described below:

Install script from source tree or git

Use stack unpack hwk or git clone https://github.com/juhp/hwk.

Then go to the source directory and run the install.sh script, which

  • first runs stack install
  • then moves the binary installed by stack install to ~/.local/lib/hwk, and sets up a wrapper script ~/.local/bin/hwk which runs it.

You may wish to change the resolver in stack.yaml first: it is also used to determine the resolver used by the created hwk wrapper script.


If you are on a Linux distro with a system installed ghc and Haskell libaries, you can install with cabal install to make use of them.


Installing by stack is better if you do not have a system ghc and/or global system Haskell libraries installed.

Alternatively to install by hand: run stack install, and then run it with stack exec hwk ... using the same resolver.

How does hwk work?

  • hwk use the hint library to evaluate haskell functions on standard input.
  • By default it splits the input to a list of lines: [String] -> ToList a
  • Use -a or --all to apply a function to all the input: String -> Tolist a

Supported return types

By default the following instances of the ToList class are defined:

  • String
  • [String]
  • [[String]]
  • Int
  • [Int]


Open an issue or pull request at https://github.com/juhp/hwk to report problems or make suggestions and contributions.

Related/alternative projects