alt.hn

7/20/2026 at 8:12:19 PM

I wrote an bash enumerator because I was sick of xargs

https://numerlab.org/2025/07/20/bashumerate-enumerator/

by wallach-game

7/21/2026 at 6:58:37 AM

> Consistent syntax — same {} placeholder for files, lines, ranges, or lists

Inconsistent syntax native bash methods so its an additional syntax to learn.

> Template mode — single-quoted commands work as shell templates: enumerate -f '*' -- 'cat {} | head -5'

Passing commands a a single string is BAD. Now you have to think about escaping and quoting. What does {} get replaced with if the enumerant contains unsafe characters? Can it be used as part of a larger argument or only on its own? Who knows, it's not bash. Compared to a bash loop its also always a subshell with all the implications that has - even find can be piped into a normal bash loop.

> Filters — --include and --exclude with glob patterns

A fraction of what find or native loops provide. And since this can't replace them in general enumerate is an additional thing to learn on top.

> Extensible — drop a file in lib/enumerators/ to add custom sources

To extend bash loops you don't even need root access, you just add the code to the loop.

by account42

7/21/2026 at 8:03:25 AM

being consistent in a sea of inconsistency is a good thing, no matter how hard you try to paint otherwise. the solution have to start at some point. But the rest, yeah, scary.

by iririririr

7/21/2026 at 6:15:11 AM

I don’t want to be a downer here, but the structure of this repo and the verbosity+language of the docs feel 80% vibecoded. Not that that’s wrong; I just feel kinda gullible for even clicking on this.

One uses xargs or parallel only a few times before they remember some of the quirks that but them. And then they become cautious. And then it’s muscle memory. And if it’s not an often occurrence, they learn to check the man page.

Anyways, in a world of “vibecoding” why add another “tool” to the mix when the LLMs have been trained on all our stackoverflow-posted grievances to begin with?

by zxexz

7/21/2026 at 9:54:06 AM

I lol'd, but do you think this is valid?

https://github.com/wallach-game/bashumerate/pull/1/files

to me looks like a right solution, even if I was also tired of writing for loops by hand usually

by giov4

7/21/2026 at 12:25:17 PM

The main reason to use xargs is to split up argument lists before they exceed the limit.

by inigyou

7/21/2026 at 10:58:26 AM

Some of these are wrong, as standard shell globs don't traverse directories. For instance the first example should be:

    ls **/*.sh
I think that would work in Bash just as well as using find.

But yeah, even in POSIX it feels redundant when we already have find, seq, grep and whatnot.

by Dibby053

7/21/2026 at 11:13:45 AM

I frequently have cases where `ls **/*.png` fails because the argument list is too long. Just happened yesterday with an rm I wanted to run.

Find works, but the syntax is arcane. Not bad, but unlike any other common cli tool, which makes it more difficult to remember if you haven't needed it in a while

by wongarsu

7/21/2026 at 11:46:33 AM

I agree and I usually ended-up combining find reliability with other commands to obtain what I needed without big issues or too much looping syntax effort.

Regarding remembering the find syntax I think its being arcane is what it made for me more easy to remember :) I now have a unique brain area dedicated to remember only that.

by giov4

7/21/2026 at 3:07:35 PM

Newer finds have a -delete option. Dunno if that's standard or some GNU addition, but it's there.

by Grimeton

7/21/2026 at 11:52:22 AM

To be pendantic

    ls -- **/*.sh
Otherwise it will fail if you've got a file named e.g. --help

by IsTom

7/21/2026 at 12:57:31 PM

So, it's essentially argument injection?

I dislike these tools so much, because you need to know all these corner-cases and I don't.

by ahoef

7/21/2026 at 2:11:21 PM

Yeah, this happens broadly in shell with globbing. It's a bit ridiculous.

by IsTom

7/21/2026 at 1:00:23 PM

But `ls -print0` is not an option;

  set -x
  mkdir test; cd "$_"
  touch "test "$'\n'"12.txt"
  ls
  for name in `ls`; do echo "$name"; done
  find
  find . -exec echo {} \;
  find . -print0
  find . -print0 | xargs -n 1 -0 echo
  #
  find . -print0 | el -0 -v -x echo
  find . -print0 | el -0 -v -x echo "{0} #"
  find . -print0 | el -0 -v -x echo '"{0}" #'
  find . -print0 | el -0 -x sh -x -c 'echo "{0} #"'
  
Though, I just realized that this doesn't work yet either:

  find . -print0 | el -0 -x -- sh -c 'set -x: echo "{0} #"'
  
westurner/dotfiles/scripts/el: "edit lines" https://github.com/westurner/dotfiles/blob/master/scripts/el...

`el -v/--verbose` is useful because it prints each input; though, I might not have written `el` if I had been aware of `xargs -n/--max-args=1`

by westurner

7/21/2026 at 4:25:32 PM

  for name in `ls`; do echo "$name"; done
is an unportable and expensive way to write

  for name in *; do printf '%s\n' "$name"; done
but you could also just

  printf '%s\n' *

by tolciho

7/21/2026 at 10:42:36 AM

On a second thought I think that the effort in trying to find a shell uncomfortability problem and trying to solve it with a "wrapped workaround" still represents positive effort and should be supported and fostered without jumping directly in 90's like rtfm mode.

especially in the case of a younger profile, learning and putting dev effort, even if vibed or redundant, its still effort and a learning activity!

https://github.com/wallach-game

so I support this even if the result and problem solving can be less significant

by giov4

7/21/2026 at 11:10:42 AM

It's possible the tool is useless and a consequence of not reading the manual, but it could just be the tool is nice but the examples are too simplistic.

In any case, toxicity aside, publishing a command line project and having someone dismiss the examples with shell oneliners is also a valuable lesson, and I don't think it will make him a worse developer.

by Dibby053

7/21/2026 at 11:52:42 AM

that's what I also thought when I saw the pull request, that it could be a useful lecture.

But again the usefulness of the final tool should not compromise appreciation of effort and learning.

Unless the tool targets, claims or pretends to be the best, final and universal solution to such problem.

I believe it isn't, I will still fall back to my bash memories, I will not need, install and use this tool, I will not need, install or use custom shells. The effort wasted in re-aligning my brain to a tool change would superseed instantly the few second effort needed to reach the needed bash one-liner.

Also, didn't you also feel good and amazed when completing a very long and nested working one-liner? wasn't that orgasmic? :D

by giov4

7/21/2026 at 6:31:57 AM

In this thread: bash experts with arcane knowledge, unintentionally demonstrating how awful bash is.

The obvious solution would be to use something more sane, like PowerShell or nushell, but instead old experts will always defend the skills they have honed for years, while criticizing anything that's different.

by IdiotSavage

7/21/2026 at 2:20:16 PM

Given the alternative proposed by OP was more of the same but with layers on top, saying "how about just using xargs and sh anyway" is a simplification -- learn 2 tiny things vs start depending on some new tool whose only purpose is to let you avoid learning those 2 tiny things by adding template language, etc., on top? I'll learn the 2.

As for widening the scope to other tools, I've written about that on here before, how I have lots of powershell experience, some nushell, etc. I haven't become a convert (definitely not on Linux, of course occasionally on Windows).

Happy to respond to any input or anything, but you should reply directly to people if you're going to criticize them -- very poor form to blanket criticize while also taking an uncharitable read.

by dundarious

7/21/2026 at 1:10:45 PM

As others have pointed out throughout the thread, the reason we defend the skills is that there’s a high likelihood that these tools will always be available on any machine; PowerShell and nushell, not so much.

by sgarland

7/21/2026 at 11:14:49 AM

Maybe it is out of habit, but I never managed to get into PowerShell, in fact, I am not at easy with the Microsoft way of doing things, with few exceptions. Too much UNIX I guess. Nushell seems to be based on the PowerShell philosophy of using structured data and not text, not my thing.

I really like the UNIX way of using text I/O, it has it flaws but it works for me. But that being said, I still hate bash and all its family. It has so many footguns it is an entire armory at this point, mostly related to spaces and escaping.

Something Perl-like could be a saner replacement. It is already a bit shell-like, it doesn't struggle with escaping the way bash does, and it has very powerful text processing abilities that go well with traditional UNIX tools.

by GuB-42

7/21/2026 at 12:59:42 PM

I'm stodgy, but I can't get past how they chose VERB-OBJECT instead of OBJECT-VERB. get-<tab> is useless. MSFT knew tab-completion would be a thing, yet they made it useless.

by avisser

7/21/2026 at 3:23:38 PM

Get-AD* is less useless, though? modules should have prefixes! (except for Exchange/ExchangeOnlineManagement who have Get-User and Get-Group, because fuck you apparently)

by Natfan

7/21/2026 at 3:14:57 PM

No, there are two problems here:

1. Things have developed over time. Bash and other shells weren't always this way. If you have ever touched different shells, awk, sed and so on and then touch perl you see how it is basically just the glue between the other tools put into one language.

2. The majority of scripts is written in sh or bash. So these shells won't go away anytime soon and any newcomer will be confronted with them. So it's best to know all the edge cases before you do stuff you don't want to do. And yes, you could always install another shell. But that brings another dependency and opens up another can of worms. In professional environments it's not really an option to have the next exotic language.

It's like having a tmux.conf on your local machine that configures tmux exactly the way you want it. Nice to have but the moment you touch any of the other billions of systems out there that run the default configuration, you might be lost because you never learned the default and only use your modified version.

by Grimeton

7/21/2026 at 6:31:10 PM

This is very true. It's why I try to keep my configs as close to default as reasonable because I know I'll be touching strange machines so best to know how it works.

Possibly more for DevOps than a dev.

by onraglanroad

7/21/2026 at 9:24:37 AM

You could also say that English is an awful language, because the spelling and the pronunciation have diverged too far. But it's the international lingua franca in most contexts, because it's the international lingua franca in most contexts.

People use Bash as the default shell for scripting, because people use Bash as the default shell for scripting. If you want to replace it, you should pick a winner and discourage the use of alternatives, especially when they are better than Bash. So don't say "use something more sane, like PowerShell or nushell". Say something like "use PowerShell, or Bash if you really have to for legacy purposes, but never use nushell for any reason" instead.

by jltsiren

7/21/2026 at 6:00:58 PM

I always avoid Bash

I prefer Almquist (ash), eg., NetBSD sh, Debian sh with tab completion, busybox ash, etc.

Powershell must be slow and/or bloated like Bash; someone wrote xargs in C++ for Windows:

https://github.com/idigdoug/TextTools/tree/main/wargs

by 1vuio0pswjnm7

7/21/2026 at 7:24:56 PM

Bash is not the default scripting shell on Debian

Given that its manpage states that Bash is slow, perhaps it is not well-suited to be a scripting shell (cf. an interactive shell)

by 1vuio0pswjnm7

7/21/2026 at 5:50:03 PM

I'm just replying reflexively because suggesting Powershell on Linux is an abomination, and because I didn't know about nushell, and it looks awesome. I wonder why the documentation is still that incomplete, though.

by ASalazarMX

7/21/2026 at 6:08:59 PM

I like Bash for its portability and pretty much no other reason. That one attribute of it is pretty hard to replicate with any other tool, at least over short time horizons

by wolttam

7/21/2026 at 12:13:49 PM

This is a sleeper option, but 'xonsh' as a Python superset is a very pleasant experience, especially when you just don't feel like learning another bespoke language for the complex stuff.

I once had to scrape the output out of something hacked together by a grad student 10 years before me, scrape yet another hacked together application, do some fancy numerics, and then plonk it into a database. I did it without tears!

by nxobject

7/21/2026 at 12:24:10 PM

Bash is for whippersnappers, us old gits use POSIX sh

by jjgreen

7/21/2026 at 12:05:45 PM

I'm sure it's essentially a familiarity thing, but PowerShell and nushell is way too much typing for me.

by ubercore

7/21/2026 at 4:25:42 PM

I can't comment on nushell, but a CLI shell that uses frequent capitalisation and the 2nd furthest printable character from the home row in every 'verb' is just hilarious.

by windward

7/21/2026 at 7:06:28 AM

Switched to Nushell and I am not looking back. I don't see any major reason why we should keep dragging Bash into the twenty first century. Nushell is the first time I feel like I can write complex systems operations in a shell without having to spend either a ton of time in the docs or being at the mercy of an LLM. It is godsend.

by lobofta

7/21/2026 at 9:18:09 AM

I tried to switch to nushell full-time but couldn't stick with it.

Ironically, the main friction point were not old-fashioned tools (which `from ssv` usually handled nicely) but the 'new generation' of core CLI tools like eza or fzf. They have really nice visualizations, but they do not output structured data as a middle step, so all the colours and lines only play havoc with nu's parsing.

Since I need to "ls" a lot more often than I need to do data manipulation, the tools won and I went back to zsh. Still keep nu around for the occasional config/data file wrangling though.

by piaste

7/21/2026 at 11:24:54 AM

Yes, Bash is filled with footguns and is awful due to that. However, it's still incredibly useful as it's everywhere and has a far greater lifespan than almost anything else. You can write scripts in PowerShell or nushell, but then find that twenty years later they're no longer usable or you find a twenty year old machine that won't have PowerShell/nushell installed.

It's not so much about defending arcane scripting skills, but that Bash functions as a lowest common denominator and is useful because of that. If you want something that works reliably over decades, then it's best not to go for an "improved" shell as it may not still be around.

I like to think of Bash script writing as the opposite of riding a bike - you have to relearn it almost every time you write a script.

by ndsipa_pomu

7/21/2026 at 1:51:44 PM

You won't find bash on BSD unless someone installed it.

by SoftTalker

7/21/2026 at 6:39:06 PM

Possibly why cloud servers are 85% Linux, 14% Windows and 1% Other (including BSD).

My main shell isn't even bash, I go with zsh, but if I'm writing a script for general use I go with bash.

by onraglanroad

7/21/2026 at 3:41:53 PM

I haven't had to admin any BSD systems, so am happy with choosing Bash. Presumably posix-compliant scripts would be used to also cope with BSD systems.

by ndsipa_pomu

7/21/2026 at 7:08:32 AM

I was the kind of shell guru whose teeth itched when they saw someone doing `grep | awk`. Then I had to try and bring Windows into a Mac+Linux CI system under Jenkins groovy files that were full of `"""sh` fragments, shell scriptlets wrapping python, etc, etc, and I don't bat (I don't groovy either).

Option 1: Learn to bat and try to translate. Hmm. No. Just no Option 2: ?

Pwsh core had just come out. My immediate thought was that it would be great material for an anti-MS-ragging blog post, but then a line leapt out at me from one article I was glossing over: "... POSIX Terminal Shell Spec ...".

I still wanted that anti-MS-ragging blog material, so I decided to try and use Pwsh as a Rosetta stone until I got to a point I could convert to a real language.

But things just began to click for me. It was like going from Perl to Python - suddenly everything is an object and you can interact with everything* that way.

There's no need for grep or awk or sed in pwsh, because the output of a shell command is an object -- a string (or []byte). It has methods.

(netstat -an).replace("192.168.86.", "10.0.100.")

6 years later, pwsh is the default shell on my Mac, Ubuntu boxes, lab vms, ... everything but my docker containers unless I'm feeling feisty.

by kfsone

7/21/2026 at 7:32:13 AM

I’m curious why it’s your default on most but not all platforms?

by no-name-here

7/21/2026 at 8:06:54 AM

ideally containers run a single process. if you're spawning shells you're doing something wrong. and idealier, you should use just bare processes with namespaces and abandon docker.

by iririririr

7/21/2026 at 12:43:15 PM

awk can do grep by itself.

by anthk

7/21/2026 at 7:36:26 AM

Yes, Bash has no place in modern software engineering.

The only reasons people still use it are historical and laziness.

If it was invented today, professionals would cringe at it.

by amelius

7/21/2026 at 7:30:14 PM

The submission begins with these examples:

    for f in *.txt; do
      wc -l "$f"
    done
   
      Or this?
   
    find . -name '*.sh' -exec wc -l {} +
   
      Or maybe you pipe into xargs and pray your filenames don't have spaces:
   
    find . -name '*.log' | xargs rm
Is that "software engineering"

Looks more like "system administration"

by 1vuio0pswjnm7

7/21/2026 at 6:25:37 AM

If you want a shell to interact with the results, you can of course just use a (sub)shell.

    ls -1 ./*.sh | xargs -rd\\n sh -c 'for i in "$@" ; do ... ; done' sh
1. not strictly necessary to use -1 as I believe all common ls detect !isatty(stdout) and produce line-by-line output anyway.

2. xargs -r just doesn't run the command if there's no input, also not strictly necessary but I'm addicted to using it because it's the sensible default to me.

3. xargs -d\\n makes it collect fields as full lines, which is what you typically want, unless you're able to generate NULs.

4. use whatever shell you want of course, but I don't use bashisms, etc., by default, /bin/sh is fine for me, even if it's dash.

5. the trailing "sh" at the end is due to a quirk of `sh -c` usage, where $0 is the first non option argument, so `printf %s\\n 1 2 3 | xargs -rd\\n sh -c 'for i in "$@" ; do printf "%s " "$i" ; done ; echo'` (note the lack of trailing "sh") would only print "2 3 " as $0 is not included in "$@" ($0 is 1, $1 is 2, $2 is 3). It's very easy to just always give the shell name itself manually as $0 instead of trying to ingest "$0" into your logic.

Of course, you could `find . -maxdepth 1 -type f -name '*.sh' -print0 | xargs -r0 ...` instead, depending on what you're up to, that may be the easiest. It's definitely the simplest -- as long as your xargs has -0 support.

by dundarious

7/21/2026 at 10:08:46 AM

> not strictly necessary to use -1 as I believe all common ls detect !isatty(stdout)

I remember, though from the dim an distant past so it could be a long-fixed bug, this not working in at least one circumstance. I've explicitly included -1 in scripted calls to ls since. Of course we are breaking the best practice rule of not trying to parse the output of ls, so problems are not unexpected…

As a generally thing I like to include directives like this in scripted calls even if they happen by default anyway, because is makes my intent clear: I expect the output to being in simple single-column format and the rest will break if it isn't. I even sometimes go as far as specifying --sort=name if nothing else in the pipeline is going to enforce that.

> as long as your xargs has -0 support

I don't think I've encountered an xargs that doesn't have this support for a long time, though I don't work with embedded stuff so maybe there are cut-down versions out there still in active use for space reasons.

The problem I've hit numerous times is wanting to do something between “find -print0” and “xargs -0” and that something not supporting NUL as the item delimiter.

by dspillett

7/21/2026 at 2:06:46 PM

I don't remember which was the odd one out, but in the 00s I was using Mac OS X and FreeBSD (and maybe some other more niche alternatives) a lot, and something didn't support xargs -0.

by dundarious

7/20/2026 at 10:11:15 PM

Not sure I see the point of this. Remembering a bunch of options on one tool is no better than a bunch of tools/constructs? Especially if the latter are useful elsewhere. And it can't be used for scripts unless you start shipping it alongside, which… nah.

Just go with

  foo | while read X; do bar "$X"; done

by eqvinox

7/21/2026 at 1:08:32 AM

Bash while loops are pretty readable and the above would be a nice to iterate over lines if it wasn't for that gnarly pipe, which is a common source of errors in this construct. Remember that a pipe starts a new shell. So:

  grep stuff file.txt | while read key value ; do [ "$key" = "target" ] && found="$value" ; done
where you might expect $found to end up with the value for the line that has "target" in the first column. Then you notice that darn pipe symbol. The variable found is set in a subshell that terminates and the value is lost. This is a problem every time you need to keep some sort of state when looping. If you can tolate a bash-ism then you could do:

  while read key value ; do [ "$key" = "target" ] && found="$value" ; done < <(grep stuff file.txt)
but that doesn't read as nice and isn't compatible. It does avoid a common source of problems though, and might be worth getting into muscle memory for the times it is needed.

by xorcist

7/21/2026 at 5:23:59 AM

You can put the "< <( foo )" before the "while" btw, for pipe-like ordering of things. All redirections can be anywhere on the command line.

by eqvinox

7/21/2026 at 2:03:25 AM

> and isn't compatible

is that a GNU v POSIX type of compatibility issue?

by dylan604

7/21/2026 at 5:14:22 AM

bash vs. POSIX sh (or some other shells)

zsh should be bash compatible on this AFAIR

by eqvinox

7/21/2026 at 12:23:16 AM

I use "| while read" as well, because it works well in a pipeline and handles embedded spaces. It doesn't handle embedded newlines, but in practice, real files have embedded spaces, while embedded newlines only happen in test cases and exploits. (You can do actual NUL-delimited reads with `-d ''`, but for a quick command-line operation that's generally not necessary, and if you're going to be that careful you probably also need `-r`.)

by JoshTriplett

7/21/2026 at 6:35:38 AM

While FTW! I just wondered whether it could be simplified because I get a bit tired of typing out my own belt and braces version of it:

  { # code that generates one item/filename per line of output }  | { while read ITEM; do # do something with "$ITEM"; done; }
So I just tried this and it seems to work for a trivial case although you need 1 escape:

  enum() {
    local source=$1; shift; local action=$1; shift  
    { eval "$source" ; } | { while read ITEM; do eval "$action"; done; }
  }

  $ enum "find /tmp" "echo found: \$ITEM"

  found: /tmp/.XIM-unix
  found: /tmp/.ICE-unix

by t43562

7/21/2026 at 1:08:19 AM

Depending on the actual command, this can be far slower and less efficient than xargs. You're creating a separate process for each invocation of bar when a lot of commands will take many targets for a single invocation.

Try this with find and grep vs xargs. There's a big difference.

by laughing_man

7/21/2026 at 5:20:37 AM

3 reasons against that:

* in a lot of cases the performance just doesn't matter

* xargs gets you the spaces in filenames landmine

* some commands don't even support multiple target filename arguments

For scripts in long term use, yeah, sure, figure out xargs maybe. Any other situation with a "| while read" solution, especially on an interactive session, is an oddball and simplicity wins.

by eqvinox

7/21/2026 at 12:07:55 PM

>* xargs gets you the spaces in filenames landmine

Ignorance of xargs gets you the landmine.

Understanding of xargs, helps you complete the mission without blowing off limbs.

    $ find . -name "Some Files With Spaces*.txt" -print0 | xargs -0 -I {} echo "Processing: {}"  # landmine avoided

by aa-jv

7/21/2026 at 5:44:23 AM

xargs supports null termination.

While it's true not every command supports multiple targets, presumably you know if you're using one of those commands.

by laughing_man

7/21/2026 at 4:41:21 PM

  printf 'silent data loss' | while read l; do printf '%s\n' "$l"; done
though at the point I need to write

  while IFS= read -r line || [ -n "$line" ]; do
    printf '%s\n' "$line"
  done
I'll use a different language.

by tolciho

7/21/2026 at 12:15:30 AM

I just use while’s default variable name, $REPLY most of the time. But `while` is my preferred tool for the xargs problem in most cases.

by fiddlerwoaroof

7/21/2026 at 12:01:29 PM

Yes, I think the author is just showing their ignorance, not actually doing anything about that ignorance, and re-inventing the wheel:

    $ find /path -name "*.pdf" -print0 | xargs -0 -I {} echo "Processing: {}" # handles paths properly, obviates the need to write anything new whatsoever
Seriously kids, learn your tools and check yourself before you wreck yourselves writing tools that really, really don't need to be written.

by aa-jv

7/21/2026 at 10:23:39 PM

find print0 with xargs 0 is such an awesome combination. One day I'll remember to use it instead of piping into while read ln; do ...

by adolph

7/21/2026 at 3:18:26 AM

> Or maybe you pipe into xargs and pray your filenames don’t have spaces…

Always use -0. Most gnu utilities support it. It makes them put a null byte after every filename instead of a newline. Completely eliminates the problem of dealing with whitespace in the filenames.

by db48x

7/21/2026 at 3:28:33 AM

To support your recommendation and redress the strawman the article postulates, the post's author could have replaced:

  find . -name '*.log' | xargs rm
With:

  find . -name '*.log' -print0 | xargs -0 rm

by AdieuToLogic

7/21/2026 at 12:49:23 PM

This one doesn't need xargs.

  find . -name '*.log' -delete

by tjalfi

7/21/2026 at 1:04:31 PM

THANK YOU. I kept nodding along to all of the xargs comments, thinking “sure, but what about the even easier solution?”

by sgarland

7/21/2026 at 1:28:11 PM

No dependency on GNU required anymore, POSIX 2024 supports it: https://blog.toast.cafe/posix2024-xcu#the-null-option

by dieulot

7/21/2026 at 9:47:15 PM

Neat, I didn’t know that! Even cooler that they’ve started to change all the core utilities to error out instead of creating a file with a newline character in it.

by db48x

7/21/2026 at 7:42:20 AM

For tools that don't support -0, you can add the NULs yourself without much fuss. It's a one-liner in awk/perl/sed. Very handy.

by jsrcout

7/21/2026 at 9:39:45 AM

If you do not have -0 options in your xargs/find, I wonder if you will have those extensions in your awk/sed. Perl is a different story.

by ykonstant

7/21/2026 at 11:21:02 AM

I think the parent was referring to using awk/sed to do the equivalent of:

    find ... | tr '\n' '\0' | xargs -0 ...
I.e., a blind replacement without the tool having any particular semantic understanding of what it's translating.

That still requires your xargs to have -0 support, though, and I'd be surprised to have that without the corresponding option on find. But I've done this before when feeding xargs from something other than find.

by MrDOS

7/21/2026 at 3:16:34 PM

It is also built on the assumption that filenames never contain newlines, which is wrong in general.

It's baffling to me that POSIX allows non-printable characters in file names, but here we are. Surely they had a reason for this decision.

by mr_mitm

7/20/2026 at 10:37:22 PM

On the topic of xargs replacements, I love gnu parallel.

The --dry-run flag of parallel made me confident to do more batch processing than I ever did with xargs.

Parallel has an option for almost everything, it's almost too much.

But I have shopped around for alternatives. The creator Ole Tange maintains a painstakingly long article of the alternatives and their differences. [0]

The gnu parallel book and reading materials [1] are excellent too.

[0] https://www.gnu.org/software/parallel/parallel_alternatives....

[1] https://www.gnu.org/software/parallel/#Tutorial

by tester457

7/20/2026 at 11:04:02 PM

I have used echo as a sort of poor mans equivalent for a safe check of a pipeline, removing the echo when I felt the rest of the pipeline was working correctly.

  shell stuff | xargs -n 1 -I % echo real command and % args
I have also been known to write scripts where instead of executing the critical parts it prints them. Then a dry run is

  script
and the real run is

  script | sh

by somat

7/21/2026 at 12:45:46 AM

Shouldn't you use echo instead of cat?

by krackers

7/21/2026 at 1:03:03 AM

yes echo, total brain fart there. corrected.

by somat

7/21/2026 at 12:28:54 AM

Love that idea, thanks for sharing

by bryancoxwell

7/20/2026 at 11:13:42 PM

Oh man, parallel is awful. I have to rant about this because I literally tried it again today morning.

Every single damn time I try parallel and decide to give it another chance, something ends up not working or causing a problem. I can never get it to just do what I want and get out of the way.

Today I foolishly thought maybe I was the one who was holding it wrong every single time in the past, so I copy pasted another command that was supposed to work, and thought surely this would be straightforward. Boy was I wrong. I got some manifesto about academic citations and plagiarism, which confused the hell out of me. After I wasted time trying to figure out how to turn off that nonsense, the app just hung there trying to figure out how long its command line can be? Literally doing nothing? What the hell? I killed it but then my terminal didn't close because every time I did this apparently some perl command was spawned in the background blocked on nothing. Why the hell was perl even relevant? Nothing I wrote used Perl. Just run the darn commands I asked in parallel, is that so hard?

by dataflow

7/20/2026 at 11:55:28 PM

> the app just hung there trying to figure out how long its command line can be?

That's common on linux. Many tools read from stdin if a file path isn't given: cat, xargs, base64, cksum, etc.

The citation thing is a little silly, I'll give you that one.

by nvme0n1p1

7/21/2026 at 5:27:25 AM

> That's common on linux. Many tools read from stdin if a file path isn't given: cat, xargs, base64, cksum, etc.

No. I did pipe to stdin. It's not my first time using Linux...

Here's a command line I ran right now, and the output I see:

  $ echo "http://www.example.com" | parallel -k -j 8 curl -s "{}"
  Academic tradition requires you to cite works you base your article on.
  [...more nonsense...]
  To silence this citation notice: run 'parallel --citation' once.
  
  parallel: Warning: Finding the maximal command line length. This may take up to 1 minute.
So I wait a few seconds... until I get fed up and look at my process list, and I see perl is just... seemingly sitting there, doing seemingly absolutely nothing. I'm not going to waste a whole minute of my life waiting for this; I see no reason competently written software should take that long just to accomplish such a simple task where nothing is remotely close to reaching any limits.

So I Ctrl+C. And then the parent perl process gets killed, but the child apparently keeps running.

I press Ctrl+D to exit the terminal, and then:

  $ # (Ctrl+D pressed)
  logout
...it just sits there waiting. Ctrl+C and Ctrl+\ do nothing. I have to kill the lingering perl process manually.

xargs Just Works without any of this nonsense, yet somehow I'm the one holding GNU parallel wrong?

by dataflow

7/21/2026 at 6:07:01 AM

> parallel: Warning: Finding the maximal command line length. This may take up to 1 minute.

> So I wait a few seconds [snip]

This warning is only ever printed if running in Cygwin, not Linux or macOS or elsewhere. Cygwin is notoriously slow.

    # This is slow on Cygwin, so give Cygwin users a warning
    if($^O eq "cygwin" or $^O eq "msys") {
    ::warning("Finding the maximal command line length. ".
          "This may take up to 1 minute.")
    }
Also note that it only figures this out first time, after which it’s cached on disk.

by darrenf

7/21/2026 at 7:44:37 AM

This is on MSYS2, yes, and that excuses absolutely nothing, because this shouldn't be happening in the first place for speed to be even relevant. At the risk of repeating myself thrice: the messages are confusing, the Ctrl+C handling is just utterly broken, the citation message adds to the confusion while being frankly obnoxious, and all of the delays and outputs are unnecessary in the first place as proven by literally every other program that doesn't make me wait a minute before I can use it the first time, including xargs. If Microsoft's own Windows tools did this, everybody would bash them (no pun intended) till the end of time. But since it's GNU Parallel and not Microsoft Parallel, it's Windows's fault for being slow and also my fault for having the audacity to expect better, apparently.

by dataflow

7/21/2026 at 11:25:05 AM

> the messages are confusing > while being frankly obnoxious

Try reading some time. It's pretty great.

> the Ctrl+C handling is just utterly broken

That's your terminal, not parallel.

> and all of the delays

Your terminal is adding the delay, not parallel. parallel is just warning you about your broken terminal. You're shooting the messenger here.

by MrDOS

7/21/2026 at 6:36:44 AM

I'm not new to command line tools, but I somehow managed to delete ~10k pictures while trying to use parallel to resize them.

I forget the details but it was some kind of surprisingly weird foot-gun behavior.

Luckily I had a backup, but it really has made me scared to try using parallel again.

by brokenmachine

7/21/2026 at 3:02:24 AM

>Why the hell was perl even relevant? Nothing I wrote used Perl.

parallel is written in perl.

by shawn_w

7/21/2026 at 1:11:35 AM

> Today I foolishly thought maybe I was the one who was holding it wrong […]

Apparently goes on to describe being confused about parallel reading from the standard input?

by fn-mote

7/21/2026 at 5:14:48 AM

This is pretty funny. You almost had me until the Perl part. Not going to get baited this time!

by tadfisher

7/21/2026 at 12:10:05 AM

Every time I’ve used Gnu Parallel on a new system it required accepting a Eula, which is annoying. I stick to xargs -P99 these days and am happier.

Utility software which has non-essential different first-run behavior is hostile to users.

by metadat

7/21/2026 at 2:28:44 AM

isn't parallel that tool that dumps some kind of begging message into your output each time you invoke it?

by sidewndr46

7/21/2026 at 3:06:29 AM

No? You can tell it to stop printing the citation notice.

by shawn_w

7/21/2026 at 7:44:42 AM

That sounds a lot more like "yes, but..." than "no"

by saghm

7/20/2026 at 11:03:24 PM

I love GNU Parallel too. I love how it's free software and how I can patch out the obnoxious citation notice.

by quotemstr

7/20/2026 at 11:54:26 PM

Parallel is ok but rush is nicer and much faster.

https://github.com/shenwei356/rush

by jeffbee

7/21/2026 at 12:15:25 AM

The rush project page on Github itself says it is only "slightly" faster.

by foobarqux

7/21/2026 at 3:12:49 AM

Modesty, I suppose. The larger your machine is, the more obviously faster it is.

by jeffbee

7/21/2026 at 6:37:11 AM

One thing with classical UNIX commands, is that you can expect to find them into random computers besides one's own laptop.

Not everyone has the luxury to only work with their own computer, or run random software on IT/customer managed systems.

by pjmlp

7/21/2026 at 9:38:45 AM

This is why I tend to stick to POSIX shell scripting these days, avoiding even bash. The restriction does make some things too painful, though. Before the latest POSIX revision, certain workflows were comically hard to do (unless you combine sh with... M4). The 2024 revision injects some much-needed sanity, but I am wondering, will random computers have shells compliant with that revision?

by ykonstant

7/21/2026 at 10:11:14 AM

Back in the day, as I mentioned around a few times, I found refuge in XEmacs, coming from the comfy Borland IDEs world.

However, I also had to get comfortable enough with vi, because most customer systems that we would be required to access on a support visit, or remotely, only had ed and vi available.

Even if we nowadays stick with Linux distros instead of UNIX in general, there is still the issue of what is there by default.

Yep POSIX shell scripting can be a bit painful, which is why knowing a bit awk, perl and sed might help as well, as they tend to be available by default.

by pjmlp

7/20/2026 at 9:54:18 PM

  find -print0 | xargs -0 -I {} "the {} iterated command"

by ggm

7/20/2026 at 10:48:30 PM

Xargs is fine, but openbsd has a -J option and every time I read the man page to figure out how to use it I read the -I and -J options and my brain glazes over.

https://man.openbsd.org/xargs

Other brain glazing obsd wierdness is it's two argument cd command, a cryptid I am unable to wrap my head around.

https://man.openbsd.org/ksh#cd~2

by somat

7/21/2026 at 12:18:40 AM

The two arg cd is pretty useful (and, zsh implements it too because cd is a shell feature): if you have parallel directory structure (e.g. the way rails does tests) you can switch from app/b/c/d to spec/b/c/f by doing `cd app spec`

by fiddlerwoaroof

7/20/2026 at 11:10:29 PM

I highly recommend memorizing the POSIX version of every *NIX command and sticking to them. 60% of the time, they work every time. (https://pubs.opengroup.org/onlinepubs/9799919799/idx/utiliti...)

by 0xbadcafebee

7/21/2026 at 12:24:37 AM

I highly recommend using whatever capabilities are convenient of any utility you're running, and not caring about what other systems do unless you're actually trying to write a portable shell script.

by JoshTriplett

7/21/2026 at 12:19:47 AM

In a world with nix and where nearly every system has zsh, restricting yourself to the POSIX version of these tools is masochistic.

by fiddlerwoaroof

7/20/2026 at 11:25:27 PM

BSD vs linux with a standards committee inbetween.

by ggm

7/20/2026 at 10:06:58 PM

And for most of those commands add a dash dash so that nothing with a dash prefix turns into options.

by koolba

7/20/2026 at 11:19:24 PM

why would you ever pipe find into xargs instead of calling -exec?

    find -exec the '{}' iterated command ';'

by em-bee

7/20/2026 at 11:25:39 PM

Because xargs is faster. Exec will invoke the command once per matching file (which is sometimes what you want, of course)!

While xargs will accumulate a bunch of file names, then when it as n names will invoke the command with those names, while continuing to accumulate names until n is reached or the pipe closes.

The size of n depends on the system, but is usually at least a thousand.

by gumby

7/20/2026 at 11:31:38 PM

the example as given does not accumulate, so that is what i worked with.

    find -exec command '{}' '+' 
accumulates file arguments too. the only advantage of xargs is that you can tell it how many arguments to accumulate,̶ ̶t̶h̶e̶ ̶d̶o̶w̶n̶s̶i̶d̶e̶ ̶o̶f̶ ̶x̶a̶r̶g̶s̶ ̶i̶s̶ ̶t̶h̶a̶t̶ ̶y̶o̶u̶ ̶h̶a̶v̶e̶ ̶t̶o̶ ̶s̶p̶e̶c̶i̶f̶y̶ ̶t̶h̶e̶ ̶n̶u̶m̶b̶e̶r̶,̶ ̶w̶h̶e̶r̶e̶a̶s̶ ̶f̶i̶n̶d̶ ̶j̶u̶s̶t̶ ̶f̶i̶t̶s̶ ̶a̶s̶ ̶m̶a̶n̶y̶ ̶a̶s̶ ̶i̶t̶ ̶c̶a̶n̶.̶

by em-bee

7/21/2026 at 1:19:43 AM

The problem with find is that you can't specify the maximum tolerated command line lengths, and find hasn't historically been very smart about it (it just had a compiled-in value). Apparently this is fixed in GNU find, but for older systems and other platforms that may still be an issue.

Another feature missing in find that xargs has is the maximum processes to start at a time. find will run the commands in sequence, but in many situations you really want to run a bunch in parallel.

by xorcist

7/21/2026 at 1:28:00 AM

good points that i wasn't aware of, thank you. though personally i rarely start huge operations that need to be parallelized so i prefer simplicity over speed.

by em-bee

7/20/2026 at 11:51:40 PM

xargs will fit as many as it can in 128 KiB or the system limit, which is smaller, so in practice, it's almost always pretty similar default packing

by unsnap_biceps

7/21/2026 at 1:00:43 AM

you are right, i forgot to check the default. fixed my comment.

by em-bee

7/20/2026 at 11:32:28 PM

The prior has a point because 98.89% of the time I type xargs -n 1 -0 and we are deep in the useless pipe argument which Rob Pike amongst others has rehearsed well.

I do it because I do it, just like why I use egrep and sed in pipes along with awk.

by ggm

7/20/2026 at 11:49:26 PM

Leah Neukirchen's lr and xe are very nice as a find and xargs replacement (although lr's test flag is way too complex). lr *.file | xe -s ' ... ' is a really great pattern for iterative scripting and hard to get wrong.

by t-3

7/21/2026 at 5:56:14 PM

> enumerate -r 1 10 -- 'printf "%02d\n" {}'

The printf zero-padding should be a built-in feature, as dealing with lots of filename structures and date structures needs zero-padding.

I often end up doing things like "for i in $(seq -w 1 100); do.." in bash.

My preference would actually be that -r does automatic zero-padding to fit the widest number that will come out of the range, and another variant like -R would suppress that behavior; but it could also be an optional switch.

It might also be nice to have the code recognize when start is greater than end, like -r 10 1, and support backwards-counting.

by martinflack

7/21/2026 at 8:08:22 AM

Did you write it or did Claude code slopcoded it for you? Claude is the contributor to all your other repositories. There is a world of difference between "here's a problem that I'm really concerned with and poured all my expertise to solve it" and "I told Claude to fix it for me and now I'm gonna abandon it as soon as I'm done with the HN advertising".

by jllyhill

7/21/2026 at 8:43:38 AM

> There is a world of difference between "here's a problem that I'm really concerned with and poured all my expertise to solve it" and "I told Claude to fix it for me and now I'm gonna abandon it as soon as I'm done with the HN advertising"

https://en.wikipedia.org/wiki/False_dilemma

by kleiba2

7/21/2026 at 12:23:38 PM

There's room for so much more innovation in the shell space. Microsoft did it with PowerShell - Linux seems to be stuck in the 1980s. You do have newer shells like fish, but they seem to only mess with the on-screen layout of the command prompt (while being stupid enough to still run within a terminal) and not the commands themselves.

I wonder if the generation one or two before mine grew up without shells and then had to make them and had no particular preconceptions, but my generation grew up treating the way shells work as a law of physics and thus doesn't innovate. Actually I wonder how much ossification is explained by this in general.

by inigyou

7/21/2026 at 12:37:52 PM

Shells imo are legacy on legacy, I like bash and zsh, they’re nonsensical but they work. Powershell is undoubtedly saner, but I hate it.

I think the whole concept could be rewritten from the ground up to be modern, but reaching critical mass and mvp is too damn difficult, and the majority of mac/Linux users probably don’t want it.

by hsbauauvhabzb

7/21/2026 at 1:05:43 PM

If you build it and it's better, they will come. None of us here are building it.

by inigyou

7/21/2026 at 12:42:10 PM

It's the opposite. Plan9's rc(1) it's much saner than Bash, Ksh and PowerShell.

by anthk

7/21/2026 at 12:55:09 PM

> Or maybe you pipe into xargs and pray your filenames don’t have spaces

So they wrote a new tool and posted it on HN before checking the manual about null character termination... Not trustable at all, what a waste of time!

by pif

7/21/2026 at 12:59:24 PM

Same thought I had, and that is where I stopped reading. All of these looping/enumerating techniques, including the weirdness with null-terminating strings to get around the shell's inherent treatment of spacing, are muscle memory for anyone that has spent more than 27 minutes in the shell at any point in the last 30 years. Yes it's weird because it's old. Deal with it. Why make yet another tool with yet another set of quirks?

by theideaofcoffee

7/21/2026 at 12:05:33 PM

> Or maybe you pipe into xargs and pray your filenames don’t have spaces:

> find . -name '*.log' | xargs rm

No need for prayer:

  find . -name '*.log' -print0 | xargs --null rm
That uses null as a delimiter instead of linebreaks.

by tom_alexander

7/21/2026 at 1:29:33 PM

Related: I wish there were a portable way for xargs to treat newlines as delimeters but not other spaces. Since 99.9% of the time that's what you want. (GNU's has this with -d/--delimiter, but BSD's, and thus macOS's, doesn't.)

--null/-0 is portable and helps, but it means the input has to be NUL-delimited, which is... rare. Sure, find has -print0 but (a) I wish I didn't need to do that, and (b) sometimes it's nice to just pipe `ls` output into xargs, without a `... | while read i; do echo -ne "${i}\0"; done | ...` kludge in the pipeline.

Because spaces in filenames is just common enough to be something that will bite you eventually, but newlines in filenames are a straight evil that you can basically always say is the filename's fault.

by ninkendo

7/21/2026 at 7:26:15 PM

> Or maybe you pipe into xargs and pray your filenames don’t have spaces

Or maybe use: `find ... -print0 | xargs -0 ...`

I guess you're still hoping your filenames don't contain an ASCII NUL, although that's a fairly reasonable assumption for all but the most paranoid use-cases.

by Borborygymus

7/21/2026 at 6:55:24 AM

Careful - you start from the POSIX terminal spec, you think maybe it would be interesting having objects instead of raw text streams, and next thing you've reinvented powershell...

(*35 years living and loving sh/ksh/bash/dash etc, only tried pwsh so I could write some comparisons and slag off MS a bit; now it's my default shell on everything)

by kfsone

7/21/2026 at 2:28:29 AM

Good idea but strange syntax. It would be more idiomatic if the command came first and the list of globs last.

Additionally the use of "--" is not what everybody expects: here it is used to introduce one argument, the command, while it's usually meant to introduce multiple arguments without worrying if they have a leading "-".

A possible revised syntax with command as the first argument followed by a list of globs optionally introduced by "--" would allow to enumerate all files with a leading "-", which the current syntax cannot:

  enumerate 'whatever {}' -- '-*'
I'm assuming "-f" for simplicity, but the same reasoning holds for "-L" too.

by teo_zero

7/21/2026 at 3:08:57 AM

I thought -- was typically a separator for passing a list of arguments directly to some subcommand

by montag

7/21/2026 at 5:54:45 AM

The historical meaning is, "do not interpret command line arguments following --"; e.g. the classical form shown by `echo > -f; rm -- -f`. Git has a more complex interpretation of it and no doubt there's others, but this root interpretation remains generally sound: It acts as a boundary between 'complex and intelligent processing of @ARGV elements' and 'every remaining element of @ARGV after -- is treated a string literal without further processing'.

by altairprime

7/20/2026 at 11:53:47 PM

I use:

  find . -name '*.log' -print0 | xargs -0 rm
For this simple example (derived from the article), find also has a delete operator.

This null termination is now a POSIX standard.

by chasil

7/21/2026 at 12:07:20 AM

Was exactly my thought: why not to use null termination?

Looks like a case where reading man page would have spared writing another copycat utility.

by ivlad

7/21/2026 at 2:33:01 AM

And null termination is guaranteed to work, because the only two characters forbidden in Unix filenames (for most varieties of Unix, I won't guarantee there aren't some weird variants out there) are / and null.

The only times I've needed something more than `find -print0 | xargs -0` has been when I need to apply logic to decide whether to process one of the files, in a way that's not easy to express in a `find` command. Then I write a small script with a for loop and if statements inside it.

But more people should know about `-print0`. It's the answer to 95% of the problems with `find | xargs`.

by rmunn

7/21/2026 at 1:26:56 AM

Yeah, and I invariably add -r to xargs, so as not to execute the command unless results come through the pipeline.

If one is working with whole lines of text, setting the delimiter to newline is often desirable:

xargs -d \\n

by Walf

7/21/2026 at 11:50:40 AM

I was also sick of bash ways of dealing with lots of data, spaces in file names, etc, so I created csv-nix-tools: https://github.com/mslusarz/csv-nix-tools

E.g. removing all temporary files without the need to deal with spaces, glob limits, or silly find syntax:

csv-ls -R -c full_path . | csv-grep -c full_path -e '~$' | csv-exec -- rm -f %full_path

by mslusarz

7/21/2026 at 12:22:40 PM

I think this post finally convinced me shells are awful and should be avoided.

by danlitt

7/21/2026 at 3:54:58 AM

Atleast follow standard practice in your example

Fails : enumerate -f '.txt' -- 'wc -l {}'

For all use cases

Correct : enumerate -f '.txt' -- 'wc -l -- {}'

by G_o_D

7/21/2026 at 10:41:11 AM

I never liked xargs either. My replacement is kind of like "xargs -n 1 -d '\n' -J '{}'", which experience has taught me is almost always what I want. It consumes all of its input before starting, so it knows how many files it has to process, and it can print progress to stderr and/or the terminal title as it goes. It can run each command via the shell if you want. It has --dry-run and --keep-going. It can read the file names from a file rather than stdin. I have a few more ideas for things it could do, but I haven't needed to add them yet.

(For enumerating files, I use find or dir/b/s, possibly combined with grep, then pipe the result in.)

People moaning about avoiding non-basic use of xargs and bash (and inadvertently demonstrating in many cases why some of us think that xargs sucks) miss a large part of the point, which is that it's nice to have a tool that does exactly what you want, and works in a way that's convenient for you, and isn't so widely used that you have to worry about modifying it. If you find the tool doesn't work the way you like, you can just change it. You don't have to be answerable to anybody else. I think tptacek's quite good essay could be relevant: https://sockpuppet.org/blog/2026/05/12/emacsification/

(You don't have to use LLMs for this! I wrote my program by hand, it's only like 250 lines of Python, and you could write one too. But, whichever barriers to entry prevent you from creating your own tools for yourself, using an LLM would probably lower at least some of them.)

by tom_

7/21/2026 at 3:23:35 AM

> Or maybe you pipe into xargs and pray your filenames don’t have spaces…

Most of this, if not all, is fixable by adding a `export IFS=$'\n'` to your bashrc. I'm not trying to disregard your project, just point out something that took me years to learn and I currently use extensively to solve this very problem. Perhaps you didn't know about it until now... :)

by gfalcao

7/21/2026 at 9:52:37 AM

Try not to do that in an uncontrolled file system. Filenames can and will have newlines, including trailing newlines, because evil people like myself inject them everywhere in our local user folders to keep sysadmins on their toes. Use the (now, finally, POSIX) -0/-print0 options for all file parsing which produces the correct behavior on all UNIX systems.

by ykonstant

7/21/2026 at 6:11:14 AM

Or, you use `xargs -0` for null termination instead of white space termination. `find` conveniently supports `-print0` that will use null character as separator.

by ivlad

7/21/2026 at 4:52:48 AM

Another trick that took me years to learn is to use `xargs -I` to split the results into "items"

For example

`ps aux | grep process-name | grep -v grep | awk '{ print $2 }' | xargs -Ieach kill -9 each`

by gfalcao

7/20/2026 at 11:34:04 PM

I have found that the most reliable way I like is to just construct the command externally and then pass to gnu parallel (mostly for --eta and --tmuxpane). And the great thing is, as others say, xargs -I. I prefer for shortness (and few collisoins), '@'

seq 1 10|xargs -I@ echo 'bash run.py @'|parallel -j 10

I know the echo is a little silly but then I can remove the |parallel and see if it's right. And if I don't want parallelism, I just pass to bash

by loremm

7/21/2026 at 12:51:50 PM

This is the way. Works very well.

by porridgeraisin

7/20/2026 at 11:24:02 PM

I wanted something simpler — one consistent way to iterate over anything.

That's not actually simpler though. Simple is removing everything unnecessary. You took commands which could already do what you wanted, and added an extra program which calls them in specific ways. This will add bugs and maintenance headaches, not be portable, etc. This is added complexity.

The reason you made this script is not because you wanted simpler, you wanted easier. There's nothing wrong with that, and I'll grant you it probably is, especially for those unaccustomed to these commands. But easier != simpler. Often you'll find that simple is hard and easy is complexity deferred.

by 0xbadcafebee

7/21/2026 at 4:27:17 AM

Hm. Underrated comment

by montag

7/21/2026 at 11:50:30 AM

Parallel and sed are already well-established tools.

by kekqqq

7/20/2026 at 11:21:59 PM

Literally just use xargs with -I {} and quotation marks?

by samtheprogram

7/21/2026 at 1:09:32 AM

That won't save you from weird file names, but null termination will.

by laughing_man

7/21/2026 at 2:20:21 AM

Passing "{}" handles most sane cases including spaces. If I'm doing bash that needs to be robust (rare and/or dotfiles) or know the folder/dataset has weird filenames, sure.

by samtheprogram

7/21/2026 at 12:31:41 PM

My Summary of comments: Multiple commands in use can interpret a series of string values in weird ways.

You need to establish that every program's interpretation points to the same object before processing the object through the command chain. Stopping a bad command is more important than running the good ones.

There is no tool that does this one job.

by guido26

7/21/2026 at 6:13:17 AM

find -print0...|xargs -0... works for me, and i don't always want to execute something and xargs can run parallel processes. i feel like this guy never bothered to read the man page.

by scrame

7/21/2026 at 7:59:30 AM

i often find xargs ends up biting me, and i have wanted some alternative for a while... but i don't think this is the one for me.

it feel like the syntax here is odd. it still requires me to write quote my command i want to run? unfortunately i'll have to pass on this.

personally i'd want some variant where i can still auto-complete commands and have just have {} as a placeholder. (maybe time to learn how to use xargs for real?)

by vladde

7/20/2026 at 11:21:55 PM

in zsh you can just write:

   for x (*.sh); echo "before $x after"
or

   for x in *.sh; echo "before $x after"
or

   for x (*.sh) { echo -n "before "; echo -n $x; echo " after" }

by raggi

7/20/2026 at 11:42:42 PM

missed the point. reason to use xargs or parallel are generally two: list of arguments is too long, or list of arguments that is kept in memory would take too much

for example

    for a in `find / ` ; do echo $a ; done
will take A LOT of memory, while using find's -exec, xargs, or parallel will not

by PunchyHamster

7/21/2026 at 6:02:33 AM

In my experience once you get to the point where you run out of space in the glob you’re often suffering with poor performance from spawning children as well and it’s time to move to a more formal program even if it’s a script, writing out work plans and completions to list files to avoid wasted time. It’s often a great guardrail to remind you to do this

by raggi

7/20/2026 at 11:53:45 PM

But bashenumerate doesn't do that? The parent is saying you should zsh shortloops instead of bashenumerate not zsh shortloops instead of xargs.

by foobarqux

7/21/2026 at 3:12:09 PM

Don't forget gnu parallel

by dtj1123

7/21/2026 at 3:37:45 AM

> Ever found yourself writing this?

  for f in *.txt; do
    wc -l "$f"
  done
No, because `wc` accepts multiple files. And the example given is incorrect for any file having a `.txt` suffix and whitespaces.

> Or this?

  find . -name '*.sh' -exec wc -l {} +
No.

> These all work, but each has its own syntax, its own flags, its own quirks. I wanted something simpler — one consistent way to iterate over anything.

And therein lies the proverbial xkcd standards[0] proof.

0 - https://xkcd.com/927/

by AdieuToLogic

7/21/2026 at 4:20:39 AM

calling it 'bashnumerate' and then have the command be 'enumerate' is confusing. find one and stick with it.

by fhn

7/21/2026 at 2:17:26 PM

y'all still write shell commands manually?

by jeffffff

7/20/2026 at 10:08:57 PM

Obligatory XKCD: https://xkcd.com/927/

by caminanteblanco

7/21/2026 at 12:20:26 AM

along with: I love standards- Theres soany to choose from!

by butvacuum

7/20/2026 at 11:43:32 PM

I feel like it could be just alias to some particular GNU Parallel set of options

by PunchyHamster

7/21/2026 at 10:57:12 AM

> and pray your filenames don’t have spaces

`find` has `-print0` and `xargs` has the matching `-0` flag for this. So this specific argument makes me doubt the author knows their tools. Stopped reading at this point.

by zombot

7/21/2026 at 2:49:27 AM

55 comments and nobody mentioned the incorrect English in the title?

by dboreham

7/21/2026 at 5:04:10 AM

I'm glad you here to save us. What would we do without you?

by fhn

7/20/2026 at 8:12:19 PM

bashumerate — iterate over files, lines, ranges, or lists with a consistent {} syntax. No for loops, no find -exec, no xargs flags to remember. enumerate -f '*.sh' -- wc -l {} enumerate -L a b c -- 'echo {}' Under 150 lines of bash, pluable sources, NUL-safe. https://github.com/wallach-game/bashumerate

by wallach-game

7/20/2026 at 9:52:49 PM

Have you seen parallel?

by figmert

7/21/2026 at 5:33:32 AM

[dead]

by ConanRus