Copy specific line from less - linux

How to copy a specific line from less ? Lets say I am opening a man ( which is by default opened by less ) and want to select and copy it to clipboard and after that lets say paste it to file opened in vim ? I don't want to use the mouse wheel to paste. I am looking for a simple Ctrl-c , Ctrl-v method as in windows.
When opening a man page I can't switch to my default editor (which is vim ) with 'v' key because less shouts with "Cannot edit standard input" error.
Thanks a lot and sorry if this question is silly.

tl;dr, use m and |.
Example:
Within the man page of less, by running man less:
7g
mx
6g
|x
xclip (Linux) or pbcopy (macOS), to copy to clipboard.
cat > file, to save to file, or cat >> file for append mode.
We would get:
less - opposite of more
 
The key things to learn are just two less commands: m (mark), and | (pipe).
Command m (mark)
Followed by any lowercase letter, marks the current position with that letter.
The marker we used above is x, as in step 2, it marked line 7 with x.
Command | (pipe)
| <m> shell-command
<m> represents any mark letter. Pipes a section of the input file to the given shell command.
The section of the file to be piped is between the first line on the current screen and the position marked by the letter.
<m> may also be ^ or $ to indicate beginning or end of file respectively. If <m> is . or <newline>, the current screen is piped.
Using |xpbcopy, we pipe the line-range [7, 6] into pbcopy, as line 6 is currently the first line on the screen, and line 7 is the one we marked as x, and pbcopy is the command to put text into the macOS clipboard.
Alternatively, use xclip on Linux, or even dd of=/path/to/file to save as a file.
Note
The text range is boundary inclusive, so both the beginning and the ending lines of the range, or at least 2 lines are copied.
We marked the range in the backward way, namely from bottom to top, otherwise, less might behave awkwardly, and throw the whole screen through the pipe.

I think I found the solution: it is using tmux. Tmux provides it's own clipboard ( correct me if I am wrong ). From tmux I can enter the copy-mode wherever I am ( in MAN pages, less, console output ) and let me to copy the content.

The current accepted answer is based on setting a mark, navigating one line up, piping the current screen up to that mark into the clipboard.
Copy 1 line into clipboard
Navigate to the line (using 1g to go the first line)
|
Press RETURN
head -1 | clip (or xclip et. al)
head -1 | tr '\n' '\' | clip
Explanation
| pipes the whole screen into the command, so navigate to where we want that to start.
2-3. | <m> shell-command ​if <m> is . or newline, the current screen is piped.
head -1 just the first line
| tr '\n' '\' replace the the carriage return with \ (for pasting to shell)
| clip pipe to clipboard (or /dev/clipboard, xclip et. al)

Short answer: Ctrl+C and Ctrl+V are associated with other actions. For instance Ctrl+C sends an interrupt signal to the foreground process. Usually you need to use Ctrl+Shift+C and Ctrl+Shift+V in order to copy and paste from a terminal.
Long answer: This very good thread from superuser.

Related

How do I insert multiple lines in command mode in VIM

I want to paste multiple lines in command mode. (After the colon) How can I do this?
When pasting either a ^m pops out or just pastes the first line.
http://vimdoc.sourceforge.net/htmldoc/cmdline.html#:bar
| can be used to separate commands, so you can give multiple commands in one
line. If you want to use | in an argument, precede it with \.
As you're trying to paste some text, it must be in a register already. I assume it is unnamed register then to execute it press :##
And, no, you cannot just insert it into the cmdline unless you've replaced all CRs with | (and even then it may not work properly depending on the command you paste).
You can put a range like this:
:for i in range(1,255) | put='192.168.0.' . i | endfor
Or if you have a text on the clipboard:
:0put +

Copy text from nano editor to shell [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
Improve this question
Is it possible to copy text from a file, opened with nano, to the shell?
I have a text file, and I want to copy several lines to the console, but I cannot find a keyboard shortcut to copy the text.
Nano to Shell:
1. Using mouse to mark the text.
2. Right-Click the mouse in the Shell.
Within Nano:
1. CTRL+6 (or CTRL+Shift+6 or hold Shift and move cursor) for Mark Set and mark what you want (the end could do some extra help).
2. ALT+6 for copying the marked text.
3. CTRL+u at the place you want to paste.
or
1. CTRL+6 (or CTRL+Shift+6 or hold Shift and move cursor) for Mark Set and mark what you want (the end could do some extra help).
2. CTRL+k for cutting what you want to copy
3. CTRL+u for pasting what you have just cut because you just want to copy.
4. CTRL+u at the place you want to paste.
Much easier method (for short pieces of text):
$ cat my_file
Ctrl+Shift+c to copy the required output from the terminal
Ctrl+Shift+v to paste it wherever you like
For whoever still looking for a copy + paste solution in nano editor
To select text
ctrl+6
Use arrow to move the cursor to where you want the mark to end
Note: If you want to copy the whole line, no need to mark just move the cursor to the line
To copy:
Press alt + 6
To paste:
Press ctrl + U
Reference
nano does not seem to have the ability to copy/paste from the global/system clipboard or shell.
However, you can copy text from one file to another using nano's file buffers. When you open another file buffer with ^R (Ctrl + r), you can use nanos built-in copy/paste functionality (outlined below) to copy between files:
M-6 (Meta + 6) to copy lines to nano's clipboard.
^K (Ctrl + k) to cut the current line and store it in nano's clipboard.
^^ (Ctrl + Shift + 6) to select text. Once you have selected the text, you can use the above commands to copy it or cut it.
^U (Ctrl + u) to paste the text from nano's clipboard.
Finally, if the above solution will not work for you and you are using a terminal emulator, you may be able to copy/paste from the global clipboard with Ctrl + Shift + c and Ctrl + Shift + v (Cmd + c and Cmd + v on OSX) respectively. screen also provides an external copy/paste that should work in nano. Finally if all you need to do is capture certain lines or text from a file, consider using grep to find the lines and xclip or xsel (or pbcopy/pbpaste on OSX) to copy them to the global clipboard (and/or paste from the clipboard) instead of nano.
The thread is quite old, but today I humbled around with the same question and all the mentioned solutions above did not help. As I wished to copy long lines my solution is - acording to what #themisterunknown wrote above - outside nano. I used awk!
awk '{ if (NR==87) print $0 }' filename
where NR==[line number] and $0 is complete line.
I don't know any way to do this directly in nano. However you can use "cat" or "grep" to display lines of your file in the console.
If you use a terminal multiplexer like "screen" you can copy and paste strings like this.
Simply use Ctrl+Shift+6 to copy current line or you can set mark using Ctrl+6 and copy multiple lines using above command as well.
Relatively straightforward solution:
From the first character you want to copy, hold Shift down and go all the way to the end.
Press Ctrl+K, which cuts the text from the file.
Press Ctrl+X, and then N to not save any changes.
Paste the cut text anywhere you want.
Alternatively, if your text fits into the screen, you can simply use mouse to select and it automatically copies it to clipboard.
The following works in Nano but also anywhere in a terminal:
Copy text from a terminal, after selecting with your mouse: Ctrl + shift + C.
And to past text in to a terminal: Ctrl + shift + V.
The copy buffer can't be accessed outside of nano, and nowhere I found any buffer file to read.
Here is a dirty alternative when in full NOX: Printing a given file line in the bash history.
So the given line is available as a command with the UP key.
sed "LINEq;d" FILENAME >> ~/.bash_history
Example:
sed "342q;d" doc.txt >> ~/.bash_history
Then to reload the history into the current session:
history -n
Or to make history reloading automatic at new prompts, paste this in .bash_profile:
PROMPT_COMMAND='history -n ; $PROMPT_COMMAND'
Note for AZERTY keyboards and very probably others layouts that require SHIFT for printing numbers from the top keys.
To toggle nano text selection (Mark Set/Unset) the shortcut is:
CTRL + SHIFT + 2
Or
ALT + a
You can then select the text with the arrows keys.
All of the others shortcuts works fine as the documentation:
CTRL + k or F9 to cut.
CTRL + u or F10 to paste.
Select the text in nano with the mouse and then right click on the mouse.
Text is now copied to your clipboard.
If it does not work try to start nano with the mouse option on :
nano -m filename
First method
This method seems to work when the content doesn't include ●.
Install xsel or similar and assign a global shortcut key for this command in your WM or DE:
xsel -o | sed -r 's/^ ?[[:digit:]]+($| +)//g' | perl -pe 's/\n/●/g' | sed -r 's/●●/\n\n/g; s/ ?● {1,}/ /g; s/●/\n/g' | xsel -b
Put this in your ~/.Xresources:
*selectToClipboard: false
Issue this in your xterm once to activate the above option:
xrdb -load ~/.Xresources
Now select the line(s) including the line numbers by pressing Shift while dragging the mouse. After the selection click your key combo; the line(s) are coppied and ready to be pasted anywhere you like.
Second method
Doesn't have the shortcoming of the first method.
Install xdotool and xsel or similar.
Put these two lines
Ctrl <Btn3Down>: select-start(PRIMARY, CLIPBOARD)
Ctrl <Btn3Up>: select-end(CLIPBOARD, PRIMARY)
in your ~/.Xresources like so:
*VT100*translations: #override \n\
Alt <Key> 0xf6: exec-formatted("xdg-open '%t'", PRIMARY, CUT_BUFFER0) \n\
Ctrl <Key>0x2bb: copy-selection(CLIPBOARD) \n\
Alt <Key>0x2bb: insert-selection(CLIPBOARD) \n\
Ctrl <Key> +: larger-vt-font() \n\
Ctrl <Key> -: smaller-vt-font() \n\
Ctrl <Btn3Down>: select-start(PRIMARY, CLIPBOARD) \n\
Ctrl <Btn3Up>: select-end(CLIPBOARD, PRIMARY)
Issue this in your xterm once to activate the above option:
xrdb -load ~/.Xresources
Create this scrip in your path:
#!/bin/bash
filepid=$(xdotool getwindowpid $(xdotool getactivewindow))
file=$(ps -p "$filepid" o cmd | grep -o --color=never "/.*")
firstline=$(xsel -b)
lastline=$(xsel)
sed -n ""$firstline","$lastline"p" "$file" | xsel -b
Assign a global shortcut key to call this script in your WM or DE.
Now when you want to copy a line (paragraph), select only the line number of that line (paragraph) by right mouse button while pressing Shift+Ctrl. After the selection click your custom global key combo you've created before. The line (paragraph) is coppied and ready to be pasted anywhere you like.
If you want to copy multiple lines, do the above for the first line and then for the last line of the range, instead of Shift+Ctrl+Btn3 (right mouse button), just select the number by left mouse button while pressing only Shift. After this, again call the script by your custom global shortcut. The range of lines are coppied and ready to pasted anywhere you like.
M-^ is copy Text. "M" in my environment is "Esc" key ! not "Ctrl";
so I use Esc + 6 to copy that.
[nano help] Escape-key
sequences are notated with the Meta (M-) symbol and can be entered using
either the Esc, Alt, or Meta key depending on your keyboard setup.
1) Ctrl + 6 to mark the text that you want to copy
2) Ctrl + k to cut the text and Ctrl + u to paste back to the original place
3) Go to the desired line where you want to paste the code marked in step (2). Ctrl + u to paste it.
Hope it helps.

less viewer: Copy all the lines to clipboard

There has already been a post in stackoverflow for VI editor for copying all the text into the clipboard. (Copy all the lines to clipboard) I want to do the same thing with the less viewer. I tried to search online for the process called "yank" and I did not find anything for it.
How do I copy all lines in the less editor into the clip board.
And I cannot close less and reopen it in vi. It is because of the fact that I have managed to load this file into the editor and while I have loaded it, the file has already been moved in the back end. It is a long story. The easiest solution for me now is to copy the contents of the file into memory.
less doesn't have a clipboard, but you may be able to get it to output what's stored in its buffers to a new file. This will only work if the entire contents of the file are buffered:
Type g to go to the top of the file
Type | (that's a pipe character, not an L or I) to indicate that you want to output to a pipe
Type $ to indicate that you want the output content to go to the end of the file
Type dd of=/path/to/new/file and press Enter
The dd command will take the piped data and save it to the file passed to the of= argument.
as an workaround you can set terminal's font size to 1, then select with mouse and copy (works for big , but not huge files).
If the file is not too big and if it fits in your terminal number of lines configured, then do the following:
Terminal > Edit > Clear to start
cat <file_name>
Terminal > Edit > Select all
Terminal > Edit > Copy

Search a file in linux and jump to position of the first find

I need help with a linux command with which I can search for a string in a text file and go to the first position this string is found and being able to scroll down and up from there.
I am looking for hours for such command. GREP will only find the occurrences, print them and exit the file. I need to be able to jump to that line and being able to scroll up and down in order to see the other lines around.
You can do that with less or vim, for example:
less +/pattern file.txt
vim +/pattern file.txt
This will open file.txt for editing and jump to the first match of "pattern", if such exists. You can move up or down with the arrow keys or with j and k.
The pattern can be a basic regular expression (BRE) that less and vim understand. For example:
less +/^settings file.txt
vim +/^settings file.txt
this will jump to the first line that starts with the string "settings".
It is simple as ever.
Go to the file path using -> cd filepath
vi filename (opening the file to search)
/<search_word> (forward slash and no space put the word you desire to search).
Hit 'n' to search forwards for the next occurrence of word named “hello”. You can press N to search backwards.
Example -> /hello
jumps to the first hello printed and keep pressing n or N for forward/backward movement
If you know the time stamp somehow or unique word then you can jump directly in one shot.

How to add line numbers to range of lines in Vim?

How can I add line numbers to a range of lines in a file opened in Vim? Not as in :set nu—this just displays line numbers—but actually have them be prepended to each line in the file?
With
:%s/^/\=line('.')/
EDIT: to sum up the comments.
This command can be tweaked as much as you want.
Let's say you want to add numbers in front of lines from a visual selection (V + move), and you want the numbering to start at 42.
:'<,'>s/^/\=(line('.')-line("'<")+42)/
If you want to add a string between the number and the old text from the line, just concatenate (with . in VimL) it to the number-expression:
:'<,'>s/^/\=(line('.')-line("'<")+42).' --> '/
If you need this to sort as text, you may want to zero pad the results, which can be done using printf for 0001, 0002 ... instead of 1, 2... eg:
:%s/^/\=printf('%04d', line('.'))/
Anyway, if you want more information, just open vim help: :h :s and follow the links (|subreplace-special|, ..., |submatch()|)
cat -n adds line numbers to its input. You can pipe the current file to cat -n and replace the current buffer with what it prints to stdout. Fortunately this convoluted solution is less than 10 characters in vim:
:%!cat -n
Or, if you want just a subselection, visually select the area, and type this:
:!cat -n
That will automatically put the visual selection markers in, and will look like this after you've typed it:
:'<,'>!cat -n
In order to erase the line numbers, I recommend using control-v, which will allow you to visually select a rectangle, you can then delete that rectangle with x.
On a GNU system: with the external nl binary:
:%!nl
With Unix-like environment, you can use cat or awk to generate a line number easily, because vim has a friendly interface with shell, so everything work in vim as well as it does in shell.
From Vim Tip28:
:%!cat -n
or
:%!awk '{print NR,$0}'
But, if you use vim in MS-DOS, of win9x, win2000, you loss these toolkit.
here is a very simple way to archive this only by vim:
fu! LineIt()
exe ":s/^/".line(".")."/"
endf
Or, a sequence composed with alphabet is as easy as above:
exe "s/^/".nr2char(line("."))."/"
You can also use a subst:
:g/^/exe ":s/^/".line(".")."^I/"
You can also only want to print the lines without adding them to the file:
"Sometimes it could be useful especially be editing large source files to print the line numbers out on paper.
To do so you can use the option :set printoptions=number:y to activate and :set printoptions=number:n to deactivate this feature.
If the line number should be printed always, place the line set printoptions=number:y in the vimrc."
First, you can remove the existing line numbers if you need to:
:%s/^[0-9]*//
Then, you can add line numbers. NR refers to the current line number starting at one, so you can do some math on it to get the numbering you want. The following command gives you four digit line numbers:
:%!awk '{print 1000+NR*10,$0}'
The "VisIncr" plugin is good for inserting columns of incrementing numbers in general (or letters, dates, roman numerals etc.). You can control the number format, padding, and so on. So insert a "1" in front of every line (via :s or :g or visual-block insert), highlight that column in visual-block mode, and run one of the commands from the plugin.
If someone wants to put a tab (or some spaces) after inserting the line numbers using the this excellent answer, here's a way. After going into the escape mode, do:
:%s/^/\=line('.').' '/
^ means beginning of a line and %s is the directive for substitution. So, we say that put a line number at the beginning of each line and add 4 spaces to it and then put whatever was the contents of the line before the substitution, and do this for all lines in the file.
This will automatically substitute it. Alternatively, if you want the command to ask for confirmation from you, then do:
:%s/^/\=line('.').' '/igc
P.S: power of vim :)
The best reply is done in a duplicate question.
In summary:
with CTRL-V then G I 0 You can insert a column of zero.
Then select the whole column and increment:
CTRL-V g CTRL-A
See also: https://vim.fandom.com/wiki/Making_a_list_of_numbers#Incrementing_selected_numbers

Resources