packages feed

jsontsv 0.1.3.1 → 0.1.4.0

raw patch · 4 files changed

+44/−34 lines, 4 filesdep ~attoparsecdep ~csvdep ~text

Dependency ranges changed: attoparsec, csv, text

Files

Main.hs view
@@ -6,10 +6,12 @@ import Data.Text (Text) import qualified Data.Text.Encoding as T (decodeUtf8) import Data.List (intersperse)+import qualified Data.List  import qualified Data.Text as T import qualified Data.Text.Lazy.IO as TL import Data.Maybe (catMaybes) import Control.Applicative+import Control.Monad (when) import Data.ByteString.Lazy as BL hiding (map, intersperse) import qualified Data.ByteString.Lazy.Char8 as BS import Data.Attoparsec.Lazy as Atto hiding (Result)@@ -25,31 +27,42 @@ import qualified Options.Applicative as O import qualified Text.CSV as CSV -data Options = Options { jsonExpr :: String, arrayDelim :: String, outputMode :: OutputMode } deriving Show+data Options = Options { jsonExpr :: String, arrayDelim :: String, outputMode :: OutputMode, showHeader :: Bool } deriving Show  data OutputMode = TSVOutput { delimiter :: String } | CSVOutput deriving (Show)  parseOpts :: O.Parser Options parseOpts = Options    <$> O.argument O.str (O.metavar "FIELDS")-  <*> O.strOption (O.metavar "STRING" <> O.value "," <> O.short 'a' <> O.help "concatentated array elem delimiter. Default to comma")-  <*> ((O.flag' CSVOutput (O.short 'c' <> O.long "csv" <> O.help "output CSV"))-       <|> (TSVOutput <$> (O.strOption (O.metavar "STRING" <> O.value "\t" <> O.short 'd' <> O.help "output field delimiter. Defaults to tab"))))+  <*> O.strOption (O.metavar "STRING" <> O.value "," <> O.short 'a' <> O.help "Concatentated array elem delimiter. Defaults to comma.")+  <*> (parseCSVMode <|> parseTSVMode)+  <*> O.flag False True (O.short 'H' <> O.help "Include headers") +parseCSVMode = O.flag' CSVOutput (O.short 'c' <> O.long "csv" <> O.help "Output CSV")++parseTSVMode = TSVOutput +    <$> (O.strOption +          (O.metavar "STRING" <> O.value "\t" <> O.short 'd' <> O.help "Output field delimiter. Defaults to tab."))+ opts = O.info (O.helper <*> parseOpts)           (O.fullDesc <> O.progDesc "Transform JSON objects to TSV" <> O.header "jsontsv")  main = do-  Options expr arrayDelim mode <- O.execParser opts+  Options expr arrayDelim mode showHeaders <- O.execParser opts   x <- BL.getContents    let xs :: [Value]       xs = decodeStream x-      ks' = parseKeyPath $ T.pack expr+      ks = parseKeyPath $ T.pack expr       arrayDelim' = T.pack arrayDelim-  -- Prelude.putStrLn $ "key Paths " ++ show ks'+  -- Prelude.putStrLn $ "key Paths " ++ show ks+  when showHeaders $ do+    let hs = words expr+    case mode of +      TSVOutput delim -> Prelude.putStrLn . Data.List.intercalate delim $ hs+      CSVOutput -> Prelude.putStrLn . CSV.printCSV $ [hs]   case mode of -    TSVOutput delim -> mapM_ (TL.putStrLn . B.toLazyText . evalToLineBuilder arrayDelim' delim ks') xs-    CSVOutput -> Prelude.putStrLn . CSV.printCSV $ map (map T.unpack . evalToList arrayDelim' ks') $  xs+    TSVOutput delim -> mapM_ (TL.putStrLn . B.toLazyText . evalToLineBuilder arrayDelim' delim ks) xs+    CSVOutput -> Prelude.putStrLn . CSV.printCSV $ map (map T.unpack . evalToList arrayDelim' ks) $  xs  decodeStream :: (FromJSON a) => BL.ByteString -> [a] decodeStream bs = case decodeWith json bs of
README.md view
@@ -1,17 +1,17 @@ # jsontsv -Transforms JSON objects into tab-separated line-oriented output, which is more-convenient for downstream processing with Unix tools like `grep`, `awk`,-`diff`, etc., and for inspecting with spreadsheet programs using a CSV output-option.+Transforms JSON objects into delimiter-separated line-oriented output, which is+more convenient for downstream processing with Unix tools like `grep`, `awk`,+`diff`, etc. Also useful for converting JSON data into spreadsheet data. CSV-style+output is also supported.  ## Synopsis -input.json:+input:  ```json {-  "title": "Terminator 2: Judgement Day",+  "title": "Terminator 2: Judgment Day",   "year": 1991,   "stars": [     {@@ -45,23 +45,23 @@ Note that this input is not actually JSON at the top-level. It is a stream of JSON objects. It can be fed into `jsontsv`: -    jsontsv 'title year stars.name ratings.imdb' < input.json+    jsontsv 'title year stars.name ratings.imdb' < input  outputs this tab-separated text:  ```tsv-Terminator 2: Judgement Day	1991	Arnold Schwarzenegger,Linda Hamilton	8.5+Terminator 2: Judgment Day	1991	Arnold Schwarzenegger,Linda Hamilton	8.5 Interstellar	2014	Matthew McConaughey,Anne Hathaway	8.9 ```  You can pick off array elements using `[i]` syntax: -    jsontsv 'title year stars[0].name' < input.json+    jsontsv 'title year stars[0].name' < input  outputs   ```tsv-Terminator 2: Judgement Day     1991    Arnold Schwarzenegger+Terminator 2: Judgment Day     1991    Arnold Schwarzenegger Interstellar    2014    Matthew McConaughey ``` @@ -80,14 +80,15 @@ ``` jsontsv -Usage: jsontsv FIELDS [-a STRING] ([-c|--csv] | [-d STRING])+Usage: jsontsv FIELDS [-a STRING] ([-c|--csv] | [-d STRING]) [-H]   Transform JSON objects to TSV  Available options:   -h,--help                Show this help text-  -a STRING                concatentated array elem delimiter. Default to comma-  -c,--csv                 output CSV-  -d STRING                output field delimiter. Defaults to tab+  -a STRING                Concatentated array elem delimiter. Defaults to comma.+  -c,--csv                 Output CSV+  -d STRING                Output field delimiter. Defaults to tab.+  -H                       Include headers ```  Input should be a stream of JSON objects of the same or mostly similar shape,@@ -97,7 +98,7 @@  [jq]:http://stedolan.github.io/jq/ -    curl -s "https://api.github.com/users/danchoi/repos?type=owner&sort=created&direction=desc" \+    curl -s "https://api.github.com/users/danchoi/repos?sort=created&direction=desc" \         | jq '.[]' | jsontsv 'id name stargazers_count open_issues_count'   outputs@@ -119,11 +120,7 @@ * Boolean values are output as `t` or `f`. * null is printed as `null` * If the leaf value is an array, it is concatenated into a single-  comma-separated string. The delimiter can be changed with the `-a` option.--## Performing post-processing on field values--Use awk!+  comma-separated string. This delimiter can be changed with the `-a` option.  ## Known alternatives  
example.json view
@@ -1,5 +1,5 @@ {-  "title": "Terminator 2: Judgement Day",+  "title": "Terminator 2: Judgment Day",   "year": 1991,   "stars": [     {"name": "Arnold Schwarzenegger"},
jsontsv.cabal view
@@ -2,7 +2,7 @@ --  see http://haskell.org/cabal/users-guide/  name:                jsontsv-version:             0.1.3.1+version:             0.1.4.0 synopsis:            JSON to TSV transformer homepage:            https://github.com/danchoi/jsontsv description:         Transforms JSON into tab-separated line-oriented output, for easier processing in Unix-style pipelines.@@ -20,12 +20,12 @@   build-depends:       base >=4.7 && <4.8                      , aeson >= 0.8.0.0                      , bytestring-                     , attoparsec >= 0.12.1.0+                     , attoparsec >= 0.12.0.0                      , containers                      , unordered-containers-                     , text >= 1.2.0.0+                     , text >= 1.0.0.0                      , vector                      , scientific                      , optparse-applicative-                     , csv >= 0.1.2+                     , csv >= 0.1.0   default-language:    Haskell2010