
Show HN: Nip – Use JavaScript instead of awk, sed, or grep - kolodny
https://github.com/kolodny/nip
======
escape_goat
I think we should all make an effort to try harder with our comments.

The author writes "this is for people who aren't 'devops' and who can't crank
out a fancy piped shell script using _awk_ and _sed_."

Whatever we may feel about people who have inexplicably failed to learn to use
_awk_ or _sed_ , or perl, or python, or ruby, criticism on the basis of these
methods being "better" (if only one learns how to use them) is a waste of
everyone's time.

If you really want to make a point about how less performant javascript is
than perl, that's a different matter. If you want to critique the goals,
concept, implimentation, or whatever, that's a different matter.

But it's simply too easy to write "why not do 'X'", especially if you're going
to ignore the fact that the constraints on the problem have already ruled out
'X' in the first place. That takes less than no thought. It takes an active
deficit of thought.

~~~
eropple
Without putting too fine a point on it, I think people should make an effort
to try harder with their tooling. "This is for people who aren't 'devops'" can
be just as easily read as "this is for people too aggressively incurious to
step outside their sinecure for even the teensiest of seconds and maybe learn
something."

Reinventing every wheel "because $my_pet_language" is fractious, generally
worse than the alternative, and creates fairly unproductive noise--I think
it's reasonable that people should catch at least a little flak for doing it.
I mean, if criticizing anti-cooperative behavior is a waste of time, what was
engaging in it? The idea that bash and GNU coreutils are "devops" tools,
instead of the tools of basically competent Unix-based software developers, is
so ludicrous as to be worth a little roasting. (And it has been a little.
Nobody here, not even me in this post, is being more than mild.)

HN doesn't go for gratuitous negativity, and that's pretty cool, but if this
thread's any measuring stick, negativity at this sort of behavior is a long
way from gratuitous.

~~~
Killswitch
In the end, nobody cares how I renamed all the images from lolimag_{i}.jpg to
2015_05_20_img_{i}.jpg, they just care that I did it.

Yeah sure if you mastered perl, grep/awk/sed and can whip up what you need in
a few seconds, more power to you, but I'm not going to waste an hour of my
time googling and reading man pages when I can take 3 seconds to write a quick
function in JavaScript to do what I need for that one task.

~~~
eropple
Learning to use sed for that kind of trivial task would take, what, a minute?
Maybe two? If you know regex, you know enough of sed to do anything, and if
you're not using regex in your JavaScript transform you're quite inarguably
(and I don't use that word lightly, but regular expressions really are
required knowledge) screwing up anyway...so what's the point?

Polluting the global namespace with yet another tool that's _worse at its job_
than the existing ones because of a particular breed of aggressive incuriosity
and epistemic closure is _real_ weird. (This isn't a failing unique to the
JavaScript community. Go people love doing this, too, creating bad solutions
to solved problems. You used to see it a lot in Ruby, but the community seems
to have grown up a little.)

~~~
jzelinskie
> Go people love doing this, too, creating bad solutions to solved problems.

My anecdote: most "Go people" doing this are actually "Go beginners" that are
still learning the language and attempting to write something familiar to
cement their understanding. I imagine this is often the case for other
languages.

~~~
falcolas
You'll also see this (that is, go replacements for common tools) as a direct
result of a Suckless challenge to do exactly that. The idea being to get rid
of the complexity of the current bash tools (let's be honest, when `cp` has
options you would expect from `rsync`, it's gotten rather complex), with the
side benefit of being statically compiled.

I'll admit, I've written a few of these myself to help nail down both my
knowledge of Go and the basic toolset I use every day. It was quite useful as
a learning tool, even though they'll never replace the originals.

Heck, I'd even recommend re-creating `dc` to anybody who is interested in
learning a language, or writing a parser/interpreter for a language.

~~~
eropple
_> You'll also see this (that is, go replacements for common tools) as a
direct result of a Suckless challenge to do exactly that._

This is what I was referring to, yeah, and it is to my mind a sign of a
certain amount of cultural insularity and maybe a little hubris.
Reimplementing something like `dc` to learn a language is great, it's when you
start movements to start replacing things--or even trying to be taken credibly
as an alternative--that I think you had best come _very_ correct or be ready
to defend your contention that the status quo is for some reason unsuitable.
"I don't already know sed" is not, to my mind, a good defense, which touched
off this subthread.

------
ajkjk
I like this a lot.

...

As a developer who, while (I like to think) competent, _hasn 't_ learned to
use sed/awk very well .. I find it aggravating and at times arrogant that
long-time users scoff at the idea of replacing them with more general and
accessible tools. Why should I have to learn an esoteric syntax with loads of
historical baggage and obtuse documentation(1), just because you put up with
it?

(1) man pages suck, sorry. Good tool documentation starts with basic examples.
If I just need to delete a line, search a file, or uncompress a tarball, I
should be able to find the simple command in O(1) lines read.

...

Case in point, there's a comment here:

"Wait: nip 'function(l) { return /^var/.test(l); }' is supposed to be better
than egrep '^var' ?"

Yes, it absolutely is better (except when performance really matters), because
it's very easy to see how to extend that to more complex things, whereas I
don't know how to extend egrep without doing lots of reading - if it's even
possible without switching tools. And because I can trivially wrap the former
in a shell script to produce the latter, more or less.

...

I feel this way about a lot of things. I think some people who 'grew up with'
certain older technologies end up saying everyone else should use them (which
may be true because they're omnipresent) and then extend that logic to say
that they're actually _good_ (which is not necessarily and often not true).

~~~
Sanddancer
One of the big reasons to learn the old fashioned tools is that they're always
there. Period. Yes, you have node on your server, and your development
machine, but what about when you need to do some work over on the database
server? Those antique shell utilities have saved my ass when my more preferred
methods weren't available to me.

Though the example in question, you're putting in a huge amount of boilerplate
code that you're going to have to write a wrapper for with each new script.
Most of the basic tools -- sed, grep, awk, even perl -- tend to have a quick
and dirty form that does what most people need, with the more powerful
portions at the ready. The "new and improved" tools tend to end up a lot like
your examples, and get swiftly ignored because it becomes a pain in the ass to
type the same thing over and over again, or they grow shortcuts and secrets as
time goes on until they too are full of history and shortcuts that only the
old timers know. Someone's going to eventually want a patch for a command line
flag that wraps all that boilerplate in, and you're going to end up with
perl's -n flag, and the horribly ugly code of

    
    
        perl -ne '/^var/ and print'
    

which will confuse beginners, and be a godsend to veterans.

~~~
zimpenfish
> what about when you need to do some work over on the database server?

You get the angry DBA coming over with a bat to smack sense into you because
You Do Not Work On Servers.

------
fineline
Why use this instead of perl/sed/awk?

Because you program in JS all day long and don't want to look up man pages
every time you want to do some simple text processing, that's why.

------
endgame
Why? (Yes, I read that section on the readme.)

If you learn sed and awk you can slice and dice text damn near everywhere. Nip
is only going to be useful where you have enough control to install it.

~~~
rwallace
If you already know sed/awk and you don't know JavaScript then as you say, it
would make sense to just use the former tools.

But for those of us for whom it's the other way round, it makes far more sense
to use the scripting language we already know for the occasional text
processing task than to spend time learning another language for the purpose.

------
ForHackernews
Unless you're really a JS-only developer, it's hard for me to see why this is
better than using Perl (or just sed/awk/grep themselves) for text-munging.

~~~
Killswitch
I don't know perl or sed/awk/grep that well, but I know JavaScript pretty damn
well.. So what do I do?

Look up man pages or Google Stack Overflow answers for 15 minutes to do what I
need?

Or I can just use nip and write a quick snippet that does what I know and move
onto what's most important, the task I was trying to accomplish.

In the end, nobody cares how I renamed all the images from lolimag_{i}.jpg to
2015_05_20_img_{i}.jpg, they just care that I did it.

~~~
riquito
I would argue that you could spend 1 hour of your time to learn the bare
minimum of sed and grep and grow as developer/*nix user.

------
ised
OK, I am an intermediate to advanced BSD sed user. I can do things with only
basic regex that I have seen others struggle to do with extended and Perl-
compatible regex.

But I am as green as it gets when it comes to Javascript.

I am sometimes forced to use a Windows workstation.

So I installed "super sed" (ssed.exe), a Windows sed, from
sed.sourceforge.net.

It is painfully slow. Ridiculously slow.

I'd like to try using Javascript to do some sed-style editing on text that
comes through the browser.

Let's say I open up the Javascript console in a browser, e.g., Chrome.

I know little of Javascript but I do know about window.location() and
XMLHttpRequest().

Assuming I can get the text I want to edit into the browser window... what do
I do next?

~~~
stygiansonic
If you have Chrome dev tools open, you can go to the console and define a
variable that holds your text using an ES6 string template, like so:

    
    
       var text = `Hello World:
       Here is a multiline
       piece of text`
    

I would then follow this guide on JavaScript regex:

[https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/R...](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions)

Here's a short example/sample, based on the text above: (You should be able to
copy-paste this directly into the console as well, following the declaration
of `text` above)

    
    
        // Logs the lines to console that match a certain regex.
        // This is a very poor approximation of grep.
        var re = /(Hello|text)/g
    
        text.split("\n").forEach(function(line) {
          if (line.match(re)) {
            console.log(line);
          }
        });
    

Using the JavaScript console of your browser is a great way to learn the
language, prototype ideas and sometimes to debug into your webapp. (Sometimes
it feels like hotswap when using the JVM :))

------
unclesaamm
I remember seeing someone who did this (for Python) with magic for auto-
importing modules. I can't seem to find it for the life of me, but that
feature was really nice.

I'll give a shoutout to a similar project I did with Python (but that doesn't
auto-import modules)
[https://github.com/samzhang111/pit](https://github.com/samzhang111/pit)

------
ajays
Wait:

    
    
        nip 'function(l) { return /^var/.test(l); }'
    

is supposed to be better than

    
    
        egrep '^var'
    
    ?

~~~
fineline
I think he was demonstrating function syntax. This shorter version also works:

nip 'return /^var/.test(line)'

An implicit return, added if the input doesn't match /[function|return]/ would
be nice, along with aliasing line as l, then you'd have:

nip '/^var/.test(l)'

------
visarga
I wrote a similar tool in Perl, called "flt" \- short for filter. It executes
the command for each line in the input file and gives me a bunch of extra
functions to work with. I use it dozens of times every day, about as often as
I use cat, grep and sort. But when the one-liner becomes 3-4 lines long, it's
time to write a proper Perl script with its own source file.

------
threatofrain
I would appreciate some more common use-case side by side comparisons. I've
been hesitant to learn awk or sed myself, instead using Ruby, but my intuition
tells me that javascript will require comfort with at least some basic
utilities library, and lacks a lot of built-in niceness that Ruby has.

------
gourneau
A Python version of this is called 'The Pyed Piper', yes it was named before
the show :p

[https://code.google.com/p/pyp/](https://code.google.com/p/pyp/)

------
vinceguidry
Most *nix machines will have Ruby already installed, it's much better suited,
right out of the box, for this kind of work than Javascript is, having
descended from Perl and all.

~~~
Killswitch
I don't know perl or Ruby, but I know JavaScript, what now?

~~~
falcolas
Identify the value that learning more than just one language would offer you,
and use the opportunity to broaden your horizons.

Javascript is not the be-all-end-all programming language. Neither is Ruby,
Awk, Haskell, or Prolog. However knowing more than one will help you grow in
your chosen profession.

------
tylermauthe
This is awesome, simple and powerful. awk and sed are especially annoying to
work with -- now I can use one of my favourite languages to do the same tasks.

I will shed a single tear for grep though.

------
selbyk
Hmmm, how performant is it?

~~~
acveilleux
There's really not that many possible way to beat GNU grep at least in the
regexp matching case. It's as close to the optimal solution as you'll find
(especially with `--mmap`) and really, as close as is possible.

~~~
bpicolo
[https://github.com/ggreer/the_silver_searcher](https://github.com/ggreer/the_silver_searcher)

~~~
acveilleux
Okay, that does sound like it might be faster. If Ag unrolls the main loop and
ignores line breaks unless there's a match, the JIT regex might well give you
the decisive speed edge. (I'm ignoring the parallel part of Ag, obviously
that's a winner in the ack use case.)

I'm going to seriously consider switching to Ag from ack, especially since my
work source tree has recently switched to an SSD.

~~~
bpicolo
That 33% gain on typing speed is the real gain ;D

