I would like to remain the only the first pattern (The "Important#") in the text.
Input:
Im port ant1 RandomJunk
Imp ortan t4 Lorum ipsum
Imp ort ant5 dolor sit amet, conse
I mport ant3 Aliquam vel nibh diam
Impo rtant 1 dignissim vel nisi vitae
Imp orta nt9 dui ut posuere rhoncu
Output:
Im port ant1
Imp ortan t4
Imp ort ant5
I mport ant3
Impo rtant 1
Imp orta nt9
New to vim and don't really understand :%s or :s
Please help
Assuming that you have to delete everything after 12th character on each line
you can use vim's search and replace:
Overall command structure:
:s/searchThis/replaceWithThis
This is a command to do the job:
:%s/\(.\{12}\).*/\1
Explanation:
% - signals to apply search and replace on each line in a file
\(.\{12}\).* - search part
\(.\{12\}\).* is a regex, (, ), {, } escaped with \ so vim
engine will understand that those are special signs. Without escaping it looks like this: (.{12}).*.
(.{12}) - capturing group, match first any 12 characters
.* - any character. zero or more times *
\1 - replace part, it means keep only first captured group after matching.
In our case those will be first 12 character on the line.
More thorough explanation on search and replace in vim wiki
Use the Jeday powers (regex) of vim:
:%s/\d \zs.*//
Read more at --> :h \zs
:%norm 3whD
% ................ in the whole file
norm ............. in normal mode
3w ............... jump 3 words
h ................ move one char to the left
D ................ delete the rest of the line
Related
I want to edit this text:
Aenean vel sem bibendum, eleifend odio a, dictum nibh.
The third word in the above line is
Morbi eget est vitae quam ultricies porta vitae quis nunc.
The third word in the above line is
Praesent accumsan ex a laoreet cursus.
The third word in the above line is
Quisque efficitur lectus at dolor mollis, sit amet tristique libero lobortis.
The third word in the above line is
to this text:
Aenean vel sem bibendum, eleifend odio a, dictum nibh.
The third word in the above line is sem
Morbi eget est vitae quam ultricies porta vitae quis nunc.
The third word in the above line is est
Praesent accumsan ex a laoreet cursus.
The third word in the above line is ex
Quisque efficitur lectus at dolor mollis, sit amet tristique libero lobortis.
The third word in the above line is lectus
To do this with Sublime
Select repeated part
ALT+F3
UpArrow
HOME
3 x CTRL+RightArrow
CTRL+Shift+LeftArrow
CTRL+C
DownArrow
END
CTRL+V
this trick is very useful in many cases.
can VIM do it?
It should work easily with a macro. If you have your cursor on the first character of the first line then:
qq: start recording macro named q
2w: advance two words
yw: yank (copy) word
j$: jump to next line and go to end of line
p: paste what you've yanked
+: go to start of next line
q: stop recording macro.
3#q: execute macro named q 3 times
As an alternative to a macro solution, you could also use a substitute command
:%s/\vis $\zs/\=split(getline(line('.')-1), ' ')[2]
breakdown
:%s/ start a substitute command
\vis $\zs/ select lines ending with "is "
use \zs to start replacing after the match
\=split(getline(line('.')-1), ' ')[2] split previous line on spaces and use the 3th item from the list
Note that to use this as a general template following has to hold
You need a search criteria to only match the lines you like to change. For your example, this is is $
You need to be able to split the previous line on something meaningfull returning the item you need in the same array position for each substituion. For you example this is by splitting on space and returning the 3th item.
Another vim solution:
:g/^/if line('.') % 2 | normal! wwyiwj$p | endif
g .................. globally
/^/ ................ on every start of line
if
line('.') % 2 ...... Mod of the integer division of line number by 2
normal! ............ normal mode
ww ................. jump to the third word
yiw ................ yank inner word (word under cursor)
j .................. go to the line below
$ .................. jump to othe end of the line
p .................. paste
I am using a function that I got from Vimcasts to preserve the cursor position when executing a command in Vim:
" A command to preserve last search and cursor position after running another
" command. See: http://vimcasts.org/episodes/tidying-whitespace/
function! Preserve(command)
" Preparation: save last search, and cursor position.
let _s=#/
let l = line(".")
let c = col(".")
" Do the business:
execute a:command
" Clean up: restore previous search history, and cursor position
let #/=_s
call cursor(l, c)
endfunction
" Strip trailing whitespace
nmap <Leader>$ :call Preserve("%s/\\s\\+$//e")<CR>
It works pretty well for the strip trailing whitespace mapping I've shown here, but not when I'm calling an external command like this:
" Reformat a plain text document to use hard wrapping and uniform spacing
" Note: This uses the BSD `fmt` program. The GNU coreutils version takes
" different options.
nmap <Leader>f :call Preserve("%!fmt -s -78")<CR>
vnoremap <Leader>f :call Preserve("'<,'>!fmt -s -78")<CR>
The first mapping works fine, but the second one exhibits a strange looping behavior. For example, if I have a text file like this:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut laboret dolore magna aliqua. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Sed ut perspiciatis unde omnis iste natus error sit. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Itaque reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
When I select those lines in visual mode to filter them, the command appears to run five times. Here's what I'm seeing in the output:
5 lines filtered
5 lines filtered
5 lines filtered
5 lines filtered
5 lines filtered
Press ENTER or type command to continue
If the file has 10 lines, then they are filtered 10 times. It still filters the area correctly, but I'm confused as to why it's looping. I think it has something to do with the Preserve function because running the command outside of preserve doesn't exhibit the looping.
Note: I think this is the appropriate place for this question, but the closing of the Vi/Vim proposal leaves me wondering where I should really be posting a question like this. Please let me know if there's a more appropriate forum for it.
When you call a function on a multi-line visual selection, that function is called for each line in the selection. Since your visual selection covers 5 lines the Preserve() function and the command you passed to it are called 5 times.
The solution is simple, add the range argument to the function definition:
function! Preserve() range
With that argument, the function is called only once and you can let it or the underlying command deal with the visual range itself.
See :help func-range.
Another – slightly dirtier – solution could be to modify your mappings to remove the range before calling the function so that it is called only once:
map <key> :<C-u>call Function(args)<CR>
See :help c_ctrl-u.
I have a large number of data in excel, which have whitespace in end of text.
Example :
"Lorem ipsum "
or
"Lorem ipsum "
How can I remove the whitespace?
Result :
"Lorem ipsum"
UPDATE :
I look the answer and worked for normal whitespace, i did research and found my whitespace is a unicode character. So i use this method and worked.
=TRIM(SUBSTITUTE(Lorem ipsum ,CHAR(160),CHAR(32)))
Thanks.
Source : http://office.microsoft.com/en-001/help/remove-spaces-and-nonprinting-characters-from-text-HP010062743.aspx?CTT=5&origin=HP010062581
If the double quotes are part of the data you could use this:
=TRIM(LEFT(A2, LEN(A2)-1))&""""
Result:
If the double quotes were only for display purposes just use this:
=TRIM(A2)
In pretty much every programming languages removing the trailing spaces is done with the TRIM() function. So for your case in excel :
=TRIM("Lorem ipsum ")
=TRIM(" Lorem ipsum")
=TRIM(" Lorem ipsum ")
=TRIM("Lorem ipsum")
Will all output the same result (without any trailing spaces):
Lorem ipsum
For more information on the trim function : http://office.microsoft.com/en-001/excel-help/trim-function-HP010062581.aspx
I'm trying to figure out a way, so far unsuccessfully, to add a new line ("\n") to a very long string.
Is there a function that will insert a new line every x amount of characters? Basically, I need to add a newline every 95 characters. Here's the text I'm working with:
MEMORANDUM FOR RECORD
SUBJECT: Subject
1) Nam fabulas mnesarchum comprehensam ne, cu ullum euismod consulatu usu. Eam alii lobortis
voluptatum id, denique eligendi pertinax quo ne. Vis congue eirmod ut. Duo probo soleat ex. Elit pertinax
abhorreant eu his, ipsum dicam dissentiunt pri id. Kasd erant dolorum id sed, ei vim partem deseruisse,
ne mea dico tantas alienum.
2) Has cu facilisis mediocritatem. Fabellas lucilius vim ex. Mei simul omnium et, wisi vidit ut ius.
Ad has erat honestatis. Malis animal aliquid id usu.
3) Nulla utinam appellantur cu qui, scripta sententiae disputando eu nam, ut pri unum labore.
Odio wisi torquatos sea cu. Ut detracto torquatos repudiandae pri. Vim puto solum epicurei at.
Per nonummy perpetua similique te, odio platonem ut pri. Mei indoctum prodesset in, eam nisl quaerendum at.
4) At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium
voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati
cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est
laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam
libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id
quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.
I'm interpreting the question as: I want to divide the text into lines of at most, but as close as possible to 95 characters, breaking on whitespace.
I'm ignoring the file IO in the other answers. Here goes:
-- Second parameter governs where to break; defaults to 80.
-- Call me like: breakAt(longstring, 95)
local function breakAt(str, lineLength)
local lineLength = lineLength or 80
-- Arrays are more efficient for large text operations.
local out = {}
-- Match line without newlines; save original newlines.
for line, breaks in str:gmatch('([^\n]+)(\n+)') do
local count = 0
-- Match whitespace with '*' to allow for the last word on the line having no adjacent whitespace.
for word, whitespace in line:gmatch('(%S+)(%s*)') do
count = count + #word
if count > lineLength then
-- If this word crosses the lineLength boundary, replace the last words' whitespace with a newline.
out[#out] = '\n'
-- The current word is the first on the new line.
count = #word
end
count = count + #whitespace
table.insert(out, word)
table.insert(out, whitespace)
end
table.insert(out, breaks)
end
return table.concat(out)
end
This'll break the string on the whitespace, maximizing the number of words on a line.
It's easy!
local text = io.open'memorandum.txt':read'*a' -- Load text from file
local n0, width = 0, 80
text = text:gsub('()(%s)',
function(n, c)
c = (n-n0 > width) and '\n' or c
n0 = (c == '\n') and n or n0
return c
end)
io.open('memorandum2.txt','w'):write(text) -- Save corrected text to file
Try print(s:gsub("("..string.rep(".",95)..")","%1\n")).
But I suspect you want to do this for each line, not for the whole text.
This will directly output any lines shorter than 95 characters, and split lines 95+ characters into 94 character chunks with a newline appended. it doesn't split on white-space, that is left as an exercise to you.
local fout = io.output(os.getenv('userprofile').. '\\desktop\\temp.txt', 'w+');
for str in string.gmatch(text, '(.-\n)') do
if str:len() > 95 then
while str:len() > 95 do
local s = str:sub(1, 94)
fout:write(s.. '\n')
str = str:sub(94)
end
else
fout:write(str)
end
end
fout:flush(); fout:close();
What do f and t commands do in vim and exactly how they work?
Your first stop with questions like these should be vim's internal help, :h f and :h t. However, in this case, those entries are a bit cryptic without an example. Suppose we had this line (^ = cursor position):
The quick brown fox jumps over the lazy dog.
^
These commands find characters on a line. So fb would place the cursor here:
The quick brown fox jumps over the lazy dog.
^
t is like f but places the cursor on the preceding character. So tb would give you:
The quick brown fox jumps over the lazy dog.
^
You can remember these commands as find and till. Also, you can prepend the commands with a number to move to the nth occurrence of that character. For example, 3fb would move to the third b to the right of the cursor. My example sentence only has one b though, so the cursor wouldn't move at all.
Just to add to Michael Kristofik's answer, no description of f or t is complete without also mentioning ;.
From this Vim cheat sheet:
; "Repeat latest f, t, F or T [count] times."
So, to continue the #MichaelKristofik's theme:
The quick brown fox jumps over the lazy dog.
^
type fo to go to the first 'o':
The quick brown fox jumps over the lazy dog.
^
and then ; to go to the next one:
The quick brown fox jumps over the lazy dog.
^
I find f and t very useful in combination with d and c. For example, ct: will let you replace everything from your cursor up to the next colon, but not delete the colon. You can remember it as "change to colon".
fx jumps to the next x on the line.
tx jumps to the character just before the next x on the line.
You can use Fx and Tx to reach the previous x.
You can use 2fx to jump to the second x on the line.
So, fFand tT are useful when you want to go quickly to the next set of parentheses (f() or delete everything from the cursor to, but excluding, the previous = (dT=) and so on…
See :h motion.txt. It will blow your mind.
Since LondonRob mentioned ;, I guess a description of the comma , command is in order. It is used very much in conjunction with these commands (when the search overshoots).
After performing a search with f, F, t or T, one could use , to repeat the search in the opposite direction.
Let's say we are at the start of this sentence, and we would like to change the elot to elit.
Lorem ipsum dolor sit amet consectetur adipiscing elot sed do eiusmod tempor.
^
I know I have to replace an o, so I perform an fo (find o) immediately. The cursor is stuck at some early o in the line! Hit ; to repeat the search in the same direction. Type type type... I should have just done it five times, but let's say I overshoot and type ; six times instead. I end up here:
Lorem ipsum dolor sit amet consectetur adipiscing elot sed do eiusmod tempor.
^
Lorem ipsum dolor sit amet consectetur adipiscing elot sed do eiusmod tempor.
^
Lorem ipsum dolor sit amet consectetur adipiscing elot sed do eiusmod tempor.
^
Lorem ipsum dolor sit amet consectetur adipiscing elot sed do eiusmod tempor.
^
Lorem ipsum dolor sit amet consectetur adipiscing elot sed do eiusmod tempor.
^
Lorem ipsum dolor sit amet consectetur adipiscing elot sed do eiusmod tempor.
^
Lorem ipsum dolor sit amet consectetur adipiscing elot sed do eiusmod tempor.
^
Now, one could just perform a , twice to repeat this search in the other direction. The cursor will reach the o in elot.
Lorem ipsum dolor sit amet, consectetur adipiscing elot, sed do eiusmod tempor.
^
Lorem ipsum dolor sit amet, consectetur adipiscing elot, sed do eiusmod tempor.
^
ri to finish the replacement.
As with most movement commands, , also take a count: [count],.
From the manual:
Repeat latest f, t, F or T in opposite direction [count] times.