How to Use moreutils: The Beginner's Guide (sponge, vidir, ts, chronic, and the Hidden Gems)
CodexFuse Team · 2026-11-07T02:48:48.167Z · 19 min read min read
How Do I Use moreutils?
moreutils is a collection of 15 small Unix tools that fill the gaps the standard toolbox leaves, and learning how to use moreutils takes seven moves: install the package, learn sponge first, rename files with vidir, edit a pipeline with vipe, timestamp output with ts, silence cron jobs with chronic, and learn the parallel name clash before it bites you. This moreutils tutorial follows the official man pages for version 0.70, with every fact checked as of November 2026.
A moreutils install gives you one package and 15 commands, and the collection has stayed small on purpose: the maintainer closed it to new-tool suggestions years ago, and no new tool has joined since 2016. CodexFuse offers no moreutils tool, so this guide teaches the real package on your own machine, not a web version of it.
Your shell already knows the coreutils family, so the Git beginner guide is the closest companion on this site when your scripts start living in a repository. The VPS hosting guide covers the Linux server where these tools earn their keep, and it is the pillar this page belongs to.
This guide opens the shell-utils lane in the dev-tools terminal cluster, and its pillar is the VPS hosting guide linked above, which covers the server this toolset is most useful on.
- Install moreutils from your package manager.
- Run sponge to rewrite a file safely from a pipeline.
- Open vidir to rename a whole directory in your editor.
- Drop vipe into a pipeline to edit the data mid-stream.
- Pipe noisy output through ts to timestamp every line.
- Wrap a cron job in chronic so it stays quiet unless it fails.
- Learn the parallel name clash before you type parallel.
What Is moreutils?
moreutils is a collection of the unix tools that nobody thought to write long ago when unix was young, in the words of its own home page. The project is maintained by Joey Hess, a Debian developer, and writers describe it as the community collection that fills coreutils gaps: small, single-job programs that the standard set never shipped. The collection holds 15 tools in version 0.70, up from 9 tools at launch, and the exact 0.70 release date is not published, so this guide dates the release to on or before 25 December 2024, when the FreeBSD port picked it up.
The tools are free under the GNU General Public License, and the whole package is tiny: the Debian download is 61.3 kB and installs to 231.0 kB, which is about 3.77 times the download size. Homebrew records 35,506 installs in the last 365 days, about 97.3 a day, against 3,589,203 total downloads, so the last year is about 0.99 percent of all downloads ever.
The collection is deliberately finished rather than abandoned: no new tool has been added since 2016, the site still lists 0.70 as current, and every major distro still ships the package. That stability is the point, because a tool you learn today will still be there in five years.
| Tool | What it does |
|---|---|
| chronic | Runs a command quietly unless it fails |
| combine | Combines two files with boolean operations |
| errno | Looks up errno names and descriptions |
| ifdata | Reads network interface info without parsing ifconfig |
| ifne | Runs a program only when stdin is not empty |
| isutf8 | Checks whether a file or stdin is UTF-8 |
| lckdo | Runs a program with a lock held |
| mispipe | Pipes two commands and returns the first exit status |
| parallel | Runs several jobs at once |
| pee | Tees stdin to several pipes |
| sponge | Soaks up stdin and writes it to a file |
| ts | Timestamps every line of stdin |
| vidir | Edits a directory in your text editor |
| vipe | Inserts your editor into a pipeline |
| zrun | Uncompresses arguments before running a command |
How Do I Install moreutils?
A moreutils install starts with your package manager, and the command is the same shape on every system: one package name, no extra repositories. Debian and Ubuntu still ship 0.69, while Homebrew, FreeBSD, and Debian unstable ship 0.70, so the version you get depends on your distro, not on the project.
| Platform | Command | Version shipped |
|---|---|---|
| Debian stable and Ubuntu | sudo apt install moreutils | 0.69-1 |
| Debian unstable | sudo apt install moreutils | 0.70-1 |
| macOS with Homebrew | brew install moreutils | 0.70 |
| FreeBSD | sysutils/moreutils port | 0.70 |
| Arch Linux | sudo pacman -S moreutils | Current version not verified at write time |
| Fedora and RHEL | sudo dnf install moreutils | Current version not verified at write time |
The 0.70 release is at most 682 days old, about 22.4 months, while the 0.69 your distro ships is 986 days old, about 2.7 years. The gap between the two releases is 304 days, and the only 0.70 changes are a vidir padding fix, zstd support in zrun, and a ts behavior fix, so 0.69 is not missing much.
# Debian, Ubuntu, and their derivatives sudo apt install moreutils # macOS with Homebrew brew install moreutils # Arch Linux sudo pacman -S moreutils # Fedora and RHEL sudo dnf install moreutils # Confirm the install which sponge man sponge
After installing, confirm the package landed by checking where sponge lives and by reading its manual page. The manual page is the authority for every tool in this guide, and the Sources section at the end links the official pages for all 15 tools.
How Does sponge Work?
The sponge command linux users reach for first is sponge, and it solves the oldest pipeline trap in the shell: a redirect empties the file before the pipeline reads it. sponge reads all of its input first and only then opens the output file, so a pipeline that reads and writes the same file finally works.
The manual page puts it plainly: sponge soaks up all its input before writing the output file, and this allows constructing pipelines that read from and write to the same file. The classic failure is sorting a file back into itself, which empties the file under a plain redirect, while sorting it through sponge keeps every line.
sponge holds all of its input in memory, so it is the right tool for config files, logs, and text, and the wrong tool for a multi-gigabyte stream. sponge writes through symlinks non-atomically, so a symlink target gets written in place instead of through the safe rename path.
| Approach | What happens to the file |
|---|---|
| Plain redirect | The shell empties the file before the pipeline reads it |
| sponge | sponge reads everything first, then writes the file |
| sponge with -a | sponge appends the new input to the original content |
| No file argument | sponge passes its input through to stdout |
When sponge can, it writes atomically by renaming a temp file into place, and it preserves the permissions of a file that already exists. The atomic path fails only when the temp directory sits on a different filesystem, and the manual page says so plainly.
# Sort a file back into itself, safely sort notes.txt | sponge notes.txt # Append new lines to the end of a file printf "buy milk\ncall bank\n" | sponge -a notes.txt # The official example: edit the password file in a pipeline sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd
How Do I Rename Files with vidir?
The vidir command opens a directory in your text editor, one filename per numbered line, and your edits become renames, deletions, and swaps when you save. Delete a line to remove its file, edit a name to rename it, and swap two numbers to swap two filenames.
vidir reads the editor from your EDITOR or VISUAL variable, so the same editor you use for code is the editor you use for filenames. The Neovim beginner guide covers the editor many terminal users pick for this job, and vidir works with any editor that can edit plain text.
# Edit the filenames of the current directory vidir # Edit only the JPEG files in a directory vidir *.jpeg # Rename files found by find, one per line find -type f | vidir -
Version 0.70 improved the zero padding of those line numbers, so large directories line up cleanly and small ones carry no padding they do not need. The erdtree beginner guide covers the tool for drawing a file tree before you rename it, and the two tools cover opposite halves of the same job.
How Do I Edit a Pipeline with vipe?
The vipe edit pipeline pattern drops your editor into the middle of a Unix pipeline: the data from the first command opens in your editor, and when you close it, the edited data flows into the second command. It is the only tool in the collection that lets you hand-edit a stream by hand.
vipe takes a --suffix argument that names the temp file extension, so an editor can switch on syntax highlighting for the data you are editing. Call it with vipe --suffix csv and the editor opens in CSV mode, which is the difference between editing blind text and editing a table.
# Edit the middle of a pipeline by hand command1 | vipe | command2 # Give the editor a CSV extension for highlighting grep "error" app.log | vipe --suffix csv | sort # Fix a list of names before it reaches the next tool cat names.txt | vipe | sort | uniq
vidir and vipe share the same editor variables, so setting EDITOR once configures both tools. Set it in your shell profile and every vidir and vipe call opens the editor you actually use.
How Do I Timestamp Output with ts?
A ts timestamp stdin habit turns an untimed log into a timed one: ts adds a timestamp to the beginning of each line of input, using the format you give it or its default of month, day, and time. The default format prints like Jan 03 14:22:10, which is readable enough for a human scanning a log.
ts in 0.70 reads only stdin, because the release removed the extra filename arguments the tool used to accept. That change closes Debian bug 1041291, and it means ts always sits in the middle of a pipeline, never at the start of one.
| Flag | What it does |
|---|---|
| No flag | Absolute timestamp, default format month day hour minute second |
| -i | Time since the previous line |
| -s | Time since ts started |
| -r | Converts existing timestamps to relative times like 15m5s ago |
| -m | Uses the monotonic clock instead of wall time |
| %.S | Subsecond resolution, like 30.00001 |
# Timestamp a ping so you can see when packets drop ping -c 2 localhost | ts # Show the gap between lines, not the clock time tail -f app.log | ts -i # Show seconds since the pipeline started make test | ts -s
The incremental modes are the ones you will reach for most: -i shows the gap between lines, which exposes the slow step, and -s shows the time since the start, which exposes the total. Both modes switch the default format to hours, minutes, and seconds.
How Do I Silence Cron Jobs with chronic?
The chronic command runs a command and shows its output only when the command fails, which is exactly the behavior a cron job needs. A successful run stays silent, so your inbox stays empty, and a failed run arrives with the full output attached.
The manual page frames it as the fix for the old dilemma: keep a command quiet and you lose the output you need when it fails, or keep it verbose and you drown in mail. chronic lets the command run verbosely always and hides the success output for you.
# A nightly backup that mails you only when it fails 0 1 * * * chronic backup # A check every 20 minutes, verbose while you debug it */20 * * * * chronic -ve my_script
Two flags tune the trigger: -v prints verbose output that separates stdout from stderr and reports the return value, and -e triggers on any stderr output even when the command exits zero. With -e alone, a command that prints to stderr but exits zero makes chronic return 2, which is the signal that something smelled wrong.
What Is moreutils parallel, and Why Does It Clash with GNU parallel?
moreutils parallel is not GNU parallel, and the two tools share a name, a job, and nothing else. The moreutils version is deliberately tiny: it runs one job per CPU by default, takes -j for a job limit, -l for a load limit, -i for argument substitution, and -n for arguments per command, and it ORs the exit statuses together so any failure fails the whole run.
The clash is real on real systems: Homebrew lists moreutils as conflicting with GNU parallel, because both install a parallel executable, and Debian ships two packages that provide the same path. The conflict is tracked in Debian bug 597050, and the safe move is to install only the parallel you actually use.
| Aspect | moreutils parallel | GNU parallel |
|---|---|---|
| Size | Tiny, one job per CPU by default | The full-featured job runner |
| Job control | -j, -l, -i, -n | A much larger option set |
| Releases | No new upstream release since 0.70 | A new release every month since 2010 |
| Exit status | ORed together, any failure fails the run | Its own exit-status rules |
| Output | Serialized through an internal pipe | Its own output handling |
# Say hello three times, in parallel parallel sh -c "echo hi; sleep 2; echo bye" -- 1 2 3 # Process three raw photos at once parallel -j 3 ufraw -o processed -- *.NEF # Run three commands side by side parallel -j 3 -- ls df "echo hi"
Pick the moreutils version when the job is simple and the script is short, and pick GNU parallel when the job needs its larger feature set. Either way, check which parallel your system installed before you trust a script that calls it.
moreutils vs coreutils: What Does the Collection Add?
The moreutils vs coreutils question has a short answer: coreutils ships the everyday verbs, and moreutils ships the tools nobody thought to write when Unix was young. The official site never names coreutils directly, so the comparison comes from the guides, and the guides agree on the shape of it.
coreutils gives you ls, cp, rm, and sort, and moreutils gives you the missing pieces around them: sponge for safe in-place writes, ts for timestamps, vidir and vipe for editing, chronic for quiet cron jobs, pee for splitting a stream, and zrun for compressed inputs. None of those jobs exists in coreutils, and that gap is the whole reason the collection exists.
The Gum beginner guide covers the other half of the modern shell toolbox: interactive prompts, while moreutils covers batch pipeline utilities. The two packages are shell-tooling kin, and they solve different jobs, so learn both and reach for the one that fits.
What Are the Hidden Gems?
Past the famous five, the collection holds ten more tools, and the hidden gems are the ones that quietly fix scripts. pee tees stdin to several pipes at once, ifne runs a program only when stdin is not empty, mispipe returns the exit status of the first command in a pipe, and combine merges two files with boolean operations.
errno looks up error names and descriptions, isutf8 checks whether input is UTF-8, ifdata reads network interface info without parsing ifconfig, and zrun uncompresses its arguments before the command runs. zrun gained zstd support in 0.70, and its supported list now reads gz, bz2, Z, xz, lzma, lzo, and zstd.
lckdo is still listed in 0.70, although util-linux ships flock for the same job, so treat lckdo as the legacy spelling and reach for flock on new scripts. The removal some guides predicted never happened, and the tool still ships in the package today.
A Day with moreutils: One Workflow, Five Tools
A realistic morning with moreutils strings five tools into one chain: chronic guards the cron job, ts timestamps the output, sponge writes the result safely, vidir renames the files, and vipe fixes the odd line by hand. Each tool does one job, and the chain reads like a sentence.
# Nightly log cleanup: quiet unless it fails, timestamped, safely written 0 2 * * * chronic sh -c "grep ERROR /var/log/app.log | ts | sponge /var/log/errors.txt" # Edit a CSV by hand in the middle of a pipeline, then save it safely cat report.csv | vipe --suffix csv | sponge report.csv
No testbed outputs were executed for this guide, so the examples above follow the official manual pages rather than a live run on the writer's machine. Read each command before you run it, and test the destructive ones on a copy first.
Seven Mistakes Beginners Make
The seven mistakes below all come from the same root: treating a small tool as if it worked like the tool it replaces. Learn each one once and the collection stays boring in the best way.
| Mistake | What to do instead |
|---|---|
| Piping a multi-gigabyte stream through sponge | Keep sponge for config files and logs, and keep huge streams out of RAM |
| Typing parallel before checking which one is installed | Confirm the package first, because two tools share the name |
| Passing a filename to ts | Pipe into ts, because 0.70 reads only stdin |
| Letting a chatty cron job mail you every night | Wrap it in chronic so it stays quiet unless it fails |
| Expecting an atomic write through a symlink | Expect an in-place write, because the rename path does not apply |
| Trusting a guide that calls 0.69 current | Take 0.70 from Homebrew or Debian unstable, or accept 0.69 knowingly |
| Renaming files one by one in a loop | Open vidir and rename the whole directory in your editor |
moreutils by the Numbers
The numbers below come from the sources in the next section, and the script that produced them is printed after the table so you can run it yourself. The 0.70 age is an upper bound, because the FreeBSD port date is the latest the release can be.
The project is 7,566 days old, which is 20.7 years, and it grew from 9 tools at launch to 15 tools in 0.70, a gain of 6 tools. Homebrew installed the package 35,506 times in the last year, about 97.3 times a day, while the 30-day pace is 74.0 a day and the 90-day pace is 73.7 a day.
The Debian package downloads 61.3 kB and installs to 231.0 kB, a ratio of 3.77, and the last year of Homebrew installs is 0.99 percent of the 3,589,203 total downloads. The 0.69 in your distro is 986 days old, about 2.7 years, and the gap between 0.69 and 0.70 is 304 days.
from datetime import date
today = date(2026, 11, 7)
def days(d): return (today - d).days
def yrs(d): return days(d) / 365.25
sponge_man = date(2006, 2, 19)
v070_latest = date(2024, 12, 25)
v069_packaged = date(2024, 2, 25)
print("0.70 age in days at most:", days(v070_latest))
print("0.70 age in months at most:", round(days(v070_latest) / 30.44, 1))
print("0.69 age in days:", days(v069_packaged))
print("0.69 age in years:", round(yrs(v069_packaged), 1))
print("days from 0.69 to 0.70:", (v070_latest - v069_packaged).days)
print("project age in days:", days(sponge_man))
print("project age in years:", round(yrs(sponge_man), 1))
print("tools at launch:", 9)
print("tools in 0.70:", 15)
print("tools added since launch:", 15 - 9)
print("Homebrew installs per day 365:", round(35506 / 365, 1))
print("Homebrew installs per day 30:", round(2220 / 30, 1))
print("Homebrew installs per day 90:", round(6630 / 90, 1))
print("install size ratio:", round(231.0 / 61.3, 2))
print("last-year share of total downloads percent:", round(35506 / 3589203 * 100, 2))
Output:
0.70 age in days at most: 682
0.70 age in months at most: 22.4
0.69 age in days: 986
0.69 age in years: 2.7
days from 0.69 to 0.70: 304
project age in days: 7566
project age in years: 20.7
tools at launch: 9
tools in 0.70: 15
tools added since launch: 6
Homebrew installs per day 365: 97.3
Homebrew installs per day 30: 74.0
Homebrew installs per day 90: 73.7
install size ratio: 3.77
last-year share of total downloads percent: 0.99
Sources
The project home page at joeyh.name/code/moreutils lists the 15 tools, the 0.70 changelog, and the git address, and the 0.70 news page names the vidir, zrun, and ts changes. The Homebrew formula page confirms 0.70 as stable, the GPL license, the conflicts with GNU parallel and others, and the install analytics, while the Debian package pages confirm 0.69-1 in trixie and 0.70-1 in sid with their sizes.
The manual pages on manpages.debian.org are the authority for sponge, vidir, vipe, ts, chronic, parallel, and zrun, and the GNU parallel comparison page explains the two parallels side by side. The Ubuntu changelog mirror dates the 0.69 packaging to 25 February 2024, the FreeBSD ports page dates the 0.70 port update to 25 December 2024, and the 2006 Linux.com piece records 9 tools and 1,329 lines at launch.
The OSTechNix guide from about 2022 and the rentes guide from 2015 are the only full-collection guides on the first page of results, and the jpospisil hidden-gems post from December 2023 is the freshest credible whole-collection piece. The copyprogramming pages are not cited here, because they carry false version claims, and no Facebook promotion applies to this article.
Frequently Asked Questions
Is moreutils free?
Yes, moreutils is free and open source under the GNU General Public License, and every tool in the package costs nothing to install or use. The package is in the standard repositories, so the install is one command on Debian, Ubuntu, macOS, and Fedora.
How do I install moreutils on Ubuntu?
Run sudo apt install moreutils, which installs version 0.69-1 on current Ubuntu releases. That version covers every tool in this guide, and Homebrew on macOS installs 0.70 if you need the newest release.
Is moreutils parallel the same as GNU parallel?
No, they are two different tools that share a name, and installing one can displace the other on some systems. moreutils parallel is the tiny per-CPU job runner, while GNU parallel is the full-featured job runner with monthly releases since 2010.
Can sponge handle very large files?
It can, but you should not let it, because the whole input sits in RAM until the write starts. Use sponge for config files, logs, and text, and keep multi-gigabyte streams on tools that stream instead of buffering.
Does moreutils work on macOS?
Yes, Homebrew installs version 0.70 with one command, and the package works the same as on Linux. Homebrew warns about the conflicts with GNU parallel and the other name clashes, so check the formula page if you already use one of those tools.




