Question
Let's say I just entered this command to get a count of how many lines contain a particular string:
me@machine $ command-producing-multi-line-output | grep -i "needle" | wc -l
Now how could I quickly replace "needle"
with some other word?
Current Inefficient Solution
Right now I:
- Press
Up
on the keyboard to load the last command. - Press
Left
orCtrl
+Left
until I reach"needle"
. - Press
Backspace
orCtrl
+w
to delete the word. - Type or paste in the new word.
- Hit
Enter
.
This seems pretty inefficient.
Attempted Non-working Solutions
I've tried to research history shortcuts like !!:sg/needle/new-needle
; but there are a few problems with this:
- You can't press
Up
to put!!:sg/needle/new-needle
back on the command line. Doing this will just show what it expands to (running right back into the original problem). - Repeating this with yet another new needle requires you to replace both
needle
andnew-needle
(i.e.!!:sg/new-needle-from-before/yet-another-new-needle
). - You need to type the entire
needle
instead of using something like!:4
or$4
(i.e.!!:sg/!:4/new-needle
or!!:sg/$4/new-needle
) to save time/keystrokes on however long the needle was.
I've also found things like !:^-3 "new-needle" !:5-$
but that also has issues:
- It expands in history so it can't be re-used quickly.
- Even if it didn't expand, you run into the original problem of needing to replace a word in the middle of a command chain.
I believe there has to be some super fast way to do what I want to do, and that some linux gurus out there know it. I would be very grateful for any input or suggestions on this.
EDIT:
Background
Just a bit of background, I work a lot with OpenStack on the command line and I find myself often needing to replace a parameter in several places within a long command chain of piped commands.
The way our OpenStack environments are configured, several engineers share a single stack
user on any number of servers, and there are several clusters within multiple environments. So a function declared within .bashrc
or .profile
file isn't really possible.
I'm hoping for something portable that can be used quickly with no or very minimal setup required. Otherwise I may just need to resort to using a solution outside of the shell entirely (such as clipboard replacement in AutoHotKey/Keyboard Maestro/AutoKey, etc.).
grep -c
instead of the UUOWC and then you would have less movement on the command line to replace the word – jesse_b Dec 19 '19 at 19:50echo needle haystack | xargs -L1 bash -c 'command-producing-multi-line-output | grep -c -i "$1"' sh
– Sergiy Kolodyazhnyy Dec 22 '19 at 08:36set +o vi
). This does help a lot assuming you are familiar with vi. There is also a mode for emacs key bindings. In your particular scenario, it would have been<Up>Fncw<newneedle><Enter>
(press Up, search for the first occurrence of "n" backwards, change the word under cursor and type the new needle, hit Enter). Using vi/emacs key bindings in the shell makes interactive sessions way faster. – Rolf Jan 01 '20 at 20:42