
Do you spend most of your time in the terminal? Are you always on the lookout to improve your terminal-fu? If you’re like me, you love learning new ways to solve problems, because they introduce concepts you never imagined before. I have five one-liner terminal commands that solve common issues, and perhaps they’ll introduce new concepts to you, too.
Related
The 8 Types of Linux Terminal Programs: Do You Know Them All?
How to tell your filters from your TUIs.
Mkdir with brace expansions
Brace expansions reduce command length and apply to anything
This first one is a reusable trick that applies beyond a single command.
mkdir –parents foo/{bar,baz}
That command will create a directory structure like:
foo/
├── bar/
└── baz/
The “–parents” (or -p) flag ensures any parent directories get created first. The curly braces are where the magic happens. In Bash, they’re called brace expansions, and they’re very simple. Bash treats the above command like:
mkdir –parents foo/bar
mkdir –parents foo/baz
You can use brace expansions with any command. From the official documentation:
chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}
Bash evaluates inner braces first, and the previous path expression becomes the following:
/usr/ucb/ex
/usr/ucb/edit
/usr/lib/ex?.?*
/usr/lib/how_ex
“?” and “*” are globs, which match any single character and zero or more characters, respectively.
I most often use straightforward brace expansions with mkdir, so don’t let the second (complex) expression discourage you.
Line or word count
Create a single stream and pipe it to wc
I use this command occasionally to count the lines of code in my software projects or words in my notes.
cat **/*.go | wc –lines # Count code lines.
cat **/*.org | wc –words # Count words in notes.
In order to do a complete count, we need a single stream of data piped into “wc.” If we just ran wc –words **/*.org, we would get hundreds of results, one for each file. Each of the listed commands pipes a single stream of data.
Diff two process outputs
Process substitutions make the diff command much more useful
You may be familiar with diff, which allows you to compare two files:
diff foo.txt bar.txt
However, you may not be aware of process substitutions. These allow you to execute any two commands and pass their outputs (as paths to temporary files) to a command like diff:
diff <(ls ./foo) <(ls ./bar)
Given a directory structure like the following (both have a file named “two”):
.
├── bar
│ ├── three
│ └── two
└── foo
├── one
└── two
The “>” signals that the right process substitution (“<(ls ./bar)”) lists a file called “three,” but the left doesn’t. The same principle applies for “<“.
A more useful approach is to take a baseline of a directory (ls ~/foo > foo-baseline.txt), and compare it to a current listing:
diff foo-baseline.txt <(ls ~/foo)
Now we can see any changes to the directory. This is particularly useful when using watch (covered next).
Process substitutions allow you to compare any two commands, so you can cast your imagination out further than a simple “ls” command.
Watch command outputs
Monitoring for changes is often required, and “watch” is flexible
The “watch” utility is very simple: it polls a command every two seconds, allowing you to monitor it for changes.
A simple example is to monitor listening ports:
watch ss -altpn
It clears the screen and displays only the command output with a small header.
The –color flag interprets ANSI codes, and –differences shows changes between iterations. However, results vary, and they’re somewhat unreliable.
We can use “watch” to monitor our directory and display a diff:
watch “bash -c ‘diff foo-baseline.txt <(ls -1 foo/)'”
The “watch” command uses sh, which does not have Bash process substitutions. Run the diff explicitly through Bash to enable them.
Creating the file (“1”) makes it appear in the diff (“2”). Now you’ll receive near-realtime updates on directory changes as a diff.
Grep between specific patterns
Sometimes you want to clip out sections of text
Grep matches entire lines, but sometimes you may only want the part that matches the pattern. For example, if you wanted to extract only the contents of an HTML tag:
The text we care about.
grep -oP ‘(?<=
).+(?=
)’
- “-o”: Return only the matching part of the line, not all of it.
- “-P”: Use Perl-compatible regex, which enables positive lookaheads and lookbehinds.
-
“(?<=
)”: A positive lookbehind. It means that, when matching the pattern (“.+”), the engine looks behind to see if “
” also matches.
- “(?=)”: A positive lookahead. It’s similar to a positive lookbehind, except it looks forward.
Essentially, regex will match against “.+” (any character, one or more) and look on either side to see if “
” and “
” also match. If they don’t, the match fails. This allows us to target “p” tags.You can use any pattern you wish; I only used HTML as an example. For instance:
grep -oP ‘(?<=foo).+(?=bar)’
That command will match anything between “foo” and “bar.”
I have a far more in-depth guide to regex that may interest you. It covers all the basic elements.
Operating System
Ubuntu Linux 22.04 LTS
CPU
13th Gen Intel Core i7-1360P
GPU
Intel Iris Xe Graphics
RAM
16GB DDR5
The Dell XPS 13 Plus with Linux combines powerful hardware and a great screen in a lightweight, great-looking chassis to create a fantastic Linux laptop.
These commands are very circumstantial but do offer insight that could apply to many others. Brace expansions apply to almost every command imaginable and are particularly useful with file system paths. Watch is something I use a lot, and diffs address circumstances where we need to monitor changes. Grep and regex are particularly powerful, but there were many occasions in the past when I couldn’t clip out specific blocks of text—now I know how, and so do you.
Related
Please stop using these 7 deprecated Linux commands
Get with the program!

