Pipeable javascript. Quickly filter, map, and reduce from the terminal

Related tags

Command Line pjs
Overview

pjs

Pipeable JavaScript - another utility like sed/awk/wc... but with JS! Quickly filter, map and reduce from the command line. Features a streaming API. Inspired by pipeable ruby.

Build Status

Overview

pjs is a cli tool that can accept input on stdin, or read from a list of files. Its filter, map and reduce options take expressions to be run, in that order, and applies them to the supplied input. The expressions themselves can contain identifiers used by keys in String.prototype, which will automatically be bound to the given line. This lets you save a bit of typing with your one-liners, while still giving you access to all your JS string functions! Check out some of the examples below to see how they translate.

# Return all lines longer than 5 chars
# => lines.filter(function(line) { return line.length > 5; });
ls -1 | pjs -f 'length > 5'

# Count characters in each line
# => lines.map(function(line) { return line.length; });
ls -1 | pjs -m 'length'

# Uppercase and pad each line
# => lines.map(function(line) { return '  ' + line.toUpperCase()"; });
ls -1 | pjs -m '"  " + toUpperCase()'

# Return lines longer than 5 chars, and remove any digits
# => lines
#      .filter(function(line) { return line.length > 5; })
#      .map(function(line) { return line.replace(/\d/g, ''); });
ls -1 | pjs -f 'length > 5' -m 'replace(/\d/g, "")'

The current line and value can also be accessed via the $ variable, and the tool supports json output.

(echo 'foo' && echo 'foobar') | pjs -jm '{name: $, length: length}'
[
{"name":"foo","length":3},
{"name":"foobar","length":6}
]

pjs also includes lodash functions, which can be accessed via the _ object, and chained using $$

echo 'hello' | pjs -m '_.upperFirst($)'
# Hello

echo 'please-titleize-this-sentence' | \
pjs -m '$$.lowerCase().split(" ").map(_.upperFirst).join(" ")'
# Please Titleize This Sentence

as well as Ramda and point-free style

echo 'please-titleize-this-sentence' | \
pjs -m "R.compose(R.replace(/(^|\s)\w/g, R.toUpper), R.replace(/-/g, ' '))"
# Please Titleize This Sentence

Installation

It can be installed via npm using:

npm install -g pipeable-js

Usage

Usage: pjs [options] [files ...]

Functions and expressions are invoked in the following order:
filter, map, reduce

All functions are passed the line ($) and index (i)
Built-in reduce functions: length, min, max, sum, avg, concat
Custom reduce expressions accept: prev, curr, i, array
Includes lodash (_), and can be chained using $$
Supports Ramda (R) and point-free style

Options:

  -h, --help               output usage information
  -V, --version            output the version number
  -i, --ignore             ignore empty lines
  -j, --json               output as json
  -f, --filter <exp>       filter by a boolean expression
  -m, --map <exp>          map values using the expression
  -r, --reduce <func|exp>  reduce using a function or expression

Examples

filter

# Print all odd lines
# awk 'NR % 2 == 1' file
pjs -f 'i % 2 == 0' file

# Print all lines greater than 80 chars in length
# awk 'length($0) > 80' file
pjs -f 'length > 80' file

map

# Remove all digits
# tr -d 0-9 < file
pjs -m "replace(/\d/g, '')" file

# Get second item of each line in csv
# awk -F "," '{print $2}' file
pjs -m 'split(",")[1]' file

reduce

# Count lines in file
# wc -l file
# awk 'END { print NR }' file
pjs -r length file

# Sum all decimal numbers in a file
# awk '{ sum += $1 } END { print sum }' file
# perl -nle '$sum += $_ } END { print $sum' file
pjs -r 'Number(prev) + Number(curr)' file
pjs -r '(+prev) + (+curr)' file
pjs -r sum file

# Concatenate all lines in multiple files
# awk '{printf $0;}' file1 file2
# cat file1 file2 | tr -d '\n'
pjs -r concat file1 file2

mixed

# Print the length of the longest line
# awk '{ if (length($0) > max) max = length($0) } END { print max }' file
pjs -m 'length' -r max file

Comparison

Features pjs pythonpy pru
Language JavaScript Python Ruby
Streaming Yes Limited [1] Yes
Implementation Streams Iterables Generators
Easy JSON output Yes No No
WebscaleTM YES No No

[1] Can't perform "tail -f logfile | py -x x"

Comments
  • templates

    templates

    @danielstjules, what do you think of a template feature? Something where you can define CommonJS-style modules for repeating filter/map/reduce tasks, like:

    ~/.config/pjs/templates/debug-log.js

    module.exports = function template (pjs) {
        return pjs
            .filter(function (item) {
                return !!~item.indexOf('DEBUG');
            })
            .map(function (item) {
                return "Found debug entry: " + item;
            });
    
            // omitting "reduce" here ...
    };
    

    could be used in pjs as:

    tail -f ~/logs/*.log | pjs -t debug-log
    
    opened by akoenig 7
  • Including support for Lodash with $$ wrapper object in map transform

    Including support for Lodash with $$ wrapper object in map transform

    This pull request includes:

    • support for lodash functions with the _ object
    • wrapper object with the $$ object
    • tests for the new functionality
    • documentation
    opened by thalesmello 5
  • Access the index from map/filter/...

    Access the index from map/filter/...

    Ok, first thing first pjs is AWESOME.

    pjs should allow us to access to the second argument from .map/.filter/... Maybe it could be something like $1 or i (since curr and prev are already available in -r reduce).

    opened by FGRibreau 4
  • Include support for Lodash?

    Include support for Lodash?

    Hello.

    I was wondering if it would be possible to include support for lodash. It includes all sorts of useful functions, which I think work great with your command line tool.

    I've create a reference implementation, in which I just required the library.

    With it, it's possible to camelize words. For example

    echo "foo_bar\nbee-bop" | pjs -m '_.camelCase($)'
    
    opened by thalesmello 3
  • Point-free support through ramda

    Point-free support through ramda

    Ramda takes a functional approach, which allows tacit programming and very robust data-less scripts.

    $ echo "Returns the elements of the given \
    list or string (or object with a slice method) \
    from fromIndex (inclusive) to toIndex (exclusive)." | \
    pjs -m 'R.slice(0, 48)'
    # Returns the elements of the given list or string
    
    echo 'please-titleize-this-sentence' | \
    pjs -m "R.compose(R.replace(/(^|\s)\w/g, R.toUpper), R.replace(/-/g, ' '))"
    # Please Titleize This Sentence
    

    And since R.compose only cares about unary functions, we can use any custom transform on the stack

    echo 'please-titleize-this-sentence' | \
    pjs -m "R.compose(encodeURIComponent, R.replace(/(^|\s)\w/g, R.toUpper), R.replace(/-/g, ' '))"
    # Please%20Titleize%20This%20Sentence
    
    opened by davidmh 1
  • Clarify access of line variable from the help menu

    Clarify access of line variable from the help menu

    I couldn't figure out how to reference the line rather than the index from the help documentation.

    Thought this might help make things clearer maybe.

    Love this tool btw :-)

    opened by halhenke 1
  • Remove leading ./ from bin path

    Remove leading ./ from bin path

    Removing the leading ./ from the pjs bin path allows npm to copy the script to my bin directory when using fish shell and fish node manager (fnm). Otherwise, no script was installed in bin.

    opened by jboxman 0
Releases(0.10.0)
Owner
Daniel St. Jules
Daniel St. Jules
Uses marked-terminal to render a README.md for any npm module in the terminal.

modhelp Uses marked-terminal to render a README.md for any npm module in the terminal. Now with built-in pager! Page up/down, arrow keys to scroll lin

Jason Livesay 23 Feb 8, 2022
Terminal ui for discord with interactive terminal

dickord why No fucking clue i was bored or something. why does it look dogshit Try and find a node module that supports terminal functions like trauma

Hima 3 Nov 7, 2022
SFDX Plugin to set Email Deliverability Access Level for an org easily and quickly via command line interface

SFDX Plugin to set Email Deliverability Access Level for an org easily and quickly via command line interface

Max Goldfarb 11 Dec 16, 2022
📜 Create mutable log lines into the terminal, and give life to your logs!

Because Logging can be pretty and fun Installation $ npm install draftlog What it does It allows you to re-write a line of your log after being writt

Ivan Seidel 1.2k Dec 31, 2022
Add a hungry turtle to your terminal and feed it every time you mistype 'npm' as 'nom'

Nom Does this ever happen to you? You happily code away on a project, navigating the command line like a pro, testing, error logging, installing packa

Meike Hankewicz 5 Apr 26, 2022
Sublime-like terminal-based text editor

slap ?? slap is a Sublime-like terminal-based text editor that strives to make editing from the terminal easier. It has: first-class mouse support (ev

slap 6.1k Jan 1, 2023
A terminal-to-gif recorder minus the headaches.

ttystudio A terminal-to-gif recorder minus the headaches. Record your terminal and compile it to a GIF or APNG without any external dependencies, bash

Christopher Jeffrey (JJ) 3.2k Dec 23, 2022
rtail(1) - Terminal output to the browser in seconds, using UNIX pipes.

rtail(1) Terminal output to the browser in seconds, using UNIX pipes. rtail is a command line utility that grabs every line in stdin and broadcasts it

Kilian Ciuffolo 1.6k Jan 6, 2023
Translations with speech synthesis in your terminal as a node package

Normit Normit is an easy way to translate stuff in your terminal. You can check out its Ruby gem version termit. Installation npm install normit -g Us

Paweł Urbanek 234 Jan 1, 2023
Terminal recorder: Record your termial session into HTML

terminal-recorder Terminal recorder allows you to record your bash session, and export it to html so then you can share it with your friends. GitHub P

Cristian Cortez 104 Mar 3, 2022
Terminal task list

listr Terminal task list Install $ npm install --save listr Usage const execa = require('execa'); const Listr = require('listr'); const tasks = new

Sam Verschueren 3.1k Jan 3, 2023
Display images in the terminal

terminal-image Display images in the terminal Works in any terminal that supports colors. In iTerm, the image will be displayed in full resolution, si

Sindre Sorhus 905 Dec 25, 2022
:rainbow: Beautiful color gradients in terminal output

gradient-string Beautiful color gradients in terminal output Install $ npm i gradient-string Usage const gradient = require('gradient-string'); cons

Boris K 864 Jan 3, 2023
Create clickable links in the terminal

terminal-link Create clickable links in the terminal Install $ npm install terminal-link Usage import terminalLink from 'terminal-link'; const link

Sindre Sorhus 539 Dec 31, 2022
Reliably get the terminal window size

term-size Reliably get the terminal window size Because process.stdout.columns doesn't exist when run non-interactively, for example, in a child proce

Sindre Sorhus 132 Oct 11, 2022
Truncate a string to a specific width in the terminal

cli-truncate Truncate a string to a specific width in the terminal Gracefully handles ANSI escapes. Like a string styled with chalk. It also supports

Sindre Sorhus 78 Oct 10, 2022
Execute shell commands in terminal

Execute shell commands in terminal

skanehira 9 Dec 11, 2021
Just a minimal library to do some terminal stuff.

Termctl A simple library to do some basic terminal stuff. Usage const termctl = require("termctl"); Note: We have tested this on Linux Mint and Window

Biraj 4 Sep 28, 2021