Fastest way(s) to move the cursor on a terminal command line?


Question

What is the best way to move around on a given very long command line in the terminal?

Say I used the arrow key or Ctrl-R to get this long command line:

./cmd --option1 --option2 --option3 --option4 --option5 --option6 --option7 --option8 --option9 --option10 --option11 --option12 --option13 --option14 --option15 --option16 --option17 --option18 --option19 --option20 --option21 --option22 --option23 --option24 --option25 --option26 --option27 --option28 --option29 --option30 --option31 --option32 --option33 --option34 --option35 --option36 --option37 --option38 --option39 --option40 --option41 --option42 --option43 --option44 --option45 --option46 --option47 --option48 --option49 --option50 

Now I need to move (starting from the beginning or the end of the line) the cursor to --option25 to modify something there.

What is the fastest way to get there? What I usually do is Ctrl-A to get to the beginning and then repeatedly Alt-F to move forward, word by word (or Ctrl-E to go the end and Alt-B to then go backward). But on a long line that takes too much time. There must be a way to search and jump directly to the part I need to modify, e.g. option25?

1
146
8/26/2015 9:40:58 AM

Accepted Answer

Since this hasn't been closed yet, here are a few more options.

  • Use Ctrl+x followed by Ctrl+e to open the current line in the editor specified by $FCEDIT or $EDITOR or emacs (tried in that order).
  • If you ran the command earlier, hit Ctrl+r for a reverse history search and type option25 (in this case). The line will be displayed. Hit Tab to start editing at this point.
  • Use history expansion with the s/// modifier. E.g. !-2:s/--option25/--newoption/ would rerun the second-to-last command, but replace option25. To modify the last ./cmd command, use the !string syntax: !./cmd:s/--option25/--newoption/
    Any delimiter may be used in place of / in the substitution.
  • If editing the previous line, you can use quick substitution: ^--option25^--newoption
  • Character search. This was mentioned by Pax, and can be done in regular emacs-mode with Ctrl+] for forward search, and Ctrl+Alt+] for backward search.

I recommend the second option. Ctrl+r is really handy and fast, no mucking about with editors, and you see the results before the command is run (unlike the history expansions).

101
10/27/2017 1:01:12 PM

To be clear, you don't want a "fast way to move the cursor on a terminal command line". What you actually want is a fast way to navigate over command line in you shell program.

Bash is very common shell, for example. It uses Readline library to implement command line input. And so to say, it is very convenient to know Readline bindings since it is used not only in bash. For example, gdb also uses Readline to process input.

In Readline documentation you can find all navigation related bindings (and more): http://www.gnu.org/software/bash/manual/bash.html#Readline-Interaction

Short copy-paste if the link above goes down:

Bare Essentials

  • Ctrl-b Move back one character.
  • Ctrl-f Move forward one character.
  • [DEL] or [Backspace] Delete the character to the left of the cursor.
  • Ctrl-d Delete the character underneath the cursor.
  • Ctrl-_ or C-x C-u Undo the last editing command. You can undo all the way back to an empty line.

Movement

  • Ctrl-a Move to the start of the line.
  • Ctrl-e Move to the end of the line.
  • Meta-f Move forward a word, where a word is composed of letters and digits.
  • Meta-b Move backward a word.
  • Ctrl-l Clear the screen, reprinting the current line at the top.

Kill and yank

  • Ctrl-k Kill the text from the current cursor position to the end of the line.
  • M-d Kill from the cursor to the end of the current word, or, if between words, to the end of the next word. Word boundaries are the same as those used by M-f.
  • M-[DEL] Kill from the cursor the start of the current word, or, if between words, to the start of the previous word. Word boundaries are the same as those used by M-b.
  • Ctrl-w Kill from the cursor to the previous whitespace. This is different than M- because the word boundaries differ.
  • Ctrl-y Yank the most recently killed text back into the buffer at the cursor.
  • M-y Rotate the kill-ring, and yank the new top. You can only do this if the prior command is C-y or M-y.

M is Meta key. For Max OS X Terminal you can enable "Use option as meta key" in Settings/Keyboard for that. For Linux its more complicated.

Update

Also note, that Readline can operate in two modes:

  • emacs mode (which is the default)
  • vi mode

To switch Bash to use vi mode:

$ set -o vi

Personaly I prefer vi mode since I use vim for text editing.

Bonus

In macOS Terminal app (and in iTerm too) you can Option-Click to move the cursor (cursor will move to clicked position). This even works inside vim.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon