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

Viewed 178464

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?

15 Answers

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).

I tend to prefer vi editing mode (since those keystrokes are embedded into my spinal cord now (the brain's not used at all), along with the CTRL-K, CTRL-X from WordStar 3.3 :-). You can use the command line set -o vi to activate it (and set -o emacs to revert).

In Vi, it would be (ESC-K to get the line up first of course) "f5;;B" (without the double quotes).

Of course, you have to understand what's on the line to get away with this. Basically, it's

f5 to find the first occurrence of "5" (in --option5).
;  to find the next one (in --option15).
;  to find the next one (in --option25).
B  to back up to the start of the word.

Let's see if the emacs aficionados can come up with a better solution, less than 5 keystrokes (although I don't want to start a religious war).

Have you thought about whether you'd maybe like to put this horrendously long command into a script? :-)

Actually, I can go one better than that: "3f5B" to find the third occurrence of "5" then back up to the start of the word.

After running the command once, run fc

It will launch $EDITOR with the previous command, then you can use your regular editor to modify the command. When you save and exit, the file will be executed.

..but, as Pax said - the command line isn't particularly good for editing absurdly long lines - why not make the command into a script?

It might not be the fastest, but this need to be here, some reading about ANSI cursor movements

ANSI escape sequences allow you to move the cursor around the screen at will. This is more useful for full screen user interfaces generated by shell scripts, but can also be used in prompts. The movement escape sequences are as follows:

- Position the Cursor:
  \033[<L>;<C>H
     Or
  \033[<L>;<C>f
  puts the cursor at line L and column C.
- Move the cursor up N lines:
  \033[<N>A
- Move the cursor down N lines:
  \033[<N>B
- Move the cursor forward N columns:
  \033[<N>C
- Move the cursor backward N columns:
  \033[<N>D

- Clear the screen, move to (0,0):
  \033[2J  or \033c
- Erase to end of line:
  \033[K

- Save cursor position:
  \033[s
- Restore cursor position:
  \033[u

(...)

Try putting in the following line of code at the prompt (it's a little clearer what it does if the prompt is several lines down the terminal when you put this in): echo -en "\033[7A\033[1;35m BASH \033[7B\033[6D" This should move the cursor seven lines up screen, print the word " BASH ", and then return to where it started to produce a normal prompt.


Examples:

Move the cursor back 7 lines:

echo -e "\033[7A"

Move the cursor to line 10, column 5:

echo -e "\033[10;5H"

Quickly echo colors codes, to colorize a program:

echo -e "\033[35;42m" ; ifconfig

One option is to use M-x shell in emacs. That provides all editing facilities and keystrokes that emacs has, so C-s can be used to search the text option25, for example.

(But I'd still prefer to be in the real terminal shell instead if someone can point me to good search and edit facilities.)

using option key and using a click the place you want to place the cursor with mouse or touchpad is you are using Mac build-in terminal.

first: export EDITOR='nano -m'

then: CTRL+X CTRL+E in sequence.

You current line will open in nano editor with mouse enable. You can click in any part of text and edit

then CTRL+X to exit and y to confirm saving.

I made a script to make the command line cursor move on mouse click :

  1. Enable xterm mouse tracking reporting
  2. Set readline bindings to consume the escape sequence generated by clicks

It can be found on github

More info on another post

Will work if echo -e "\e[?1000;1006;1015h" # Enable tracking print escape sequences on terminal when clicking with mouse

Related