In my gvim file I have something like below
Before line
name1/name2/name3/
next line
name2/name3 is the pattern of my interest.
I want to delete the line containing the pattern and the next line of matched pattern.
I want to save the both lines in other file. I am able to search and delete the lines using global
:g/name2\/name3/,+1d
but not able to redirect it into other file.
How can I save the grep output to some other file.
You can use write >> f to append to the file f (or write! >> f if you want to create f if it doesn't exist).
:g/name2\/name3/,+ write! >> f | ,+d
Alternatively you could use :redir >> (which avoids repeating the ,+ range) :
:g/name2\/name3/,+1d | redir! >> f | silent echon #" | redir END
Maybe there is a better solution, but after you deleted the lines they are in the " register (you can check with :reg).
Just open a new buffer with :new, paste the register with p and save the file with :w myfilename
Related
I try to use this command to write down my file name when I press the binding key.
:put!=expand('%:t:r')
I want to improve it
Because I only use this command while I am writting markdown.
So I want to add "#" and " " to the head of the file name
I try a lot but didn't works, so how can I achieve.
you can use the "concatenate strings" operator . to prepend '# ' (or whatever string you want) to the expanded filename:
:put = '# ' . expand('%:t:r')
I have files that have a header file that I need to remove.
/***....*
.
.
.
***.....*/
It is a block like this.
I have used a sed command to remove this block.
sed -i '0,/^\/*\*/d' filename
It only removes the first line of the block comment (e.g) /***....*
and I wish for it to remove the whole block.
I have tried using:
sed -i '/^.*\/\/*/d' filename, but that removes all occurrences of /*...*/
This awk will remove the block:
cat file
Beginning
/***....*
.
.
.
***.....*/
End of block
Some data
awk '/^\/\*\*/ {f=1} !f; /^\*\*/ {f=0}' file
Beginning
End of block
Some data
/^\/\*\*/ {f=1} If line starts with /** set flag f to 1
!f; If flag is not set print the line
/^\*\*/ {f=0} if line starts with ** clear flag f
I am trying to replace text inside a text file according to a certain criteria.
For example, if I have three text files, with outer.txt containing:
Blah Blah Blah
INCLUDE inner1.txt
Etcetera Etcetera
INCLUDE inner2.txt
end of file
And inner1.txt containing:
contents of inner1
And inner2.txt containing:
contents of inner2
At the end of the replacement, the outer.txt file would look like:
Blah Blah Blah
contents of inner1
Etcetera Etcetera
contents of inner2
end of file
The overall pattern would be that for every instance of the word "INCLUDE", replace that entire line with the contents of the file whose filename immediately follows that instance of "INCLUDE", which in one case would be inner1.txt and in the second case would be inner2.txt.
Put more simply, is it possible for gawk to be able to determine which text file is to be embedded into the outer text file based on the very contents to be replaced in the outer text file?
With gnu sed
sed -E 's/( *)INCLUDE(.*)/printf "%s" "\1";cat \2/e' outer.txt
If you set the +x bit on the edit-file ('chmod +x edit-file'), then you can do:
g/include/s//cat/\
.w\
d\
r !%
w
q
Explanation:
g/include/s//cat/\
Starts a global command.
.w\
(from within the global context), overwrites the edit-file with the current line only (effectively: 'cat included_file', where you replace included_file for the filename in question.)
d\
(from within the global context), deletes the current line from the buffer. (i.e. deletes 'include included_file', again, included_file standing for the file in question).
r !%
(from within the global context), reads the output from executing the default file (which is file we are editing, and was overwritten above with 'cat...').
w
(finally, outside the global context). Writes (saves) the buffer back to the edit-file.
q
quit.
With GNU awk:
awk --load readfile '{if ($1=="INCLUDE") {printf readfile($2)} else print}' outer.txt
Another ed approach would be something like:
#!/bin/sh
ed -s outer.txt <<-'EOF'
/Blah Blah Blah/+1kx
/end of file/-1ky
'xr inner.txt
'xd
'yr inner2.txt
'yd
%p
Q
EOF
Change Q to w if in-place editing is required
Remove the %p to silence the output.
I am trying to append the content of a file before the closing body tag in an html document. I've tried
cat test.html | sed -e $'/<\/body>/{ r insert.html ... }'
using various combinations of \np, \nd at ..., but everything seems to be inserted after the tag.
It would also be nice if additional string constants could be added around the content of insert.html, such as centering tags etc.
If sed is your hard requirement, you can try this in GNU sed:
sed '/<\/body>/e cat insert.html' test.html
It uses GNU-specific e shell-command (e cat filename here), which will, unlike r filename be executed before the end of the current cycle (before </body> line is processed/printed).
Note (from the docs) r filename will:
Queue the contents of filename to be read and inserted into the output stream at the end of the current cycle, or when the next input line is read.
and e command:
[...] unlike the r command, the output of the command will be printed immediately; the r command instead delays the output to the end of the current cycle.
I have come up with a perl script that outputs a template for documenting functions and structures given the definition of a function/struct from my C code.
To use it , i visually select the definition of the struct, yank and paste it right above the original definition, and invoke the script on this pasted struct. It replaces it with document for that struct.
Now is there a way that will avoid that yank paste? I am looking for a way to invoke a shell command but the output from that should be pasted somewhere else in the file, not necessarily on top of it.
IOW
:'a,'b!perl ~/bin/document.pl
replaces text between mark a and markb, I want to add the output of document.pl above mark a.
One possible solution would be to modify the perl script in a way that it also outputs its input at the end. Then you would end up with the desired result.
If you have zsh as your shell, you can use co-process:
'a,'b!coproc perl ~/bin/document.pl ; tee >&p | cat <&p
To get output before your text (this command puts it after), you should use a slightly more complex command:
'a,'b!coproc perl ~/bin/document.pl ; tee >&p | cat <(<&p) -
System-independent solution, using vim and temporary buffer:
'a,'byank a | new | 0put a | $d | execute "%!perl ~/bin/document.pl" | %d a | bw! | 'a-1put a
Try with something like this:
function! MyFunc() range
" Preserve the register.
let old_reg = #a
exec a:firstline.','.a:lastline.'yank a'
" Change to do what you need with register a.
" Insert output before a:firstline
exec (a:firstline - 1).'read !your magic with '.#a
" Restore the register
let #a = old_reg
endfunction
" :2,5MyOwn will process lines from 2 to 5 and insert the output before line 2
command! -bar -range -nargs=? MyOwn <line1>,<line2>call MyFunc()