问题
I want to delete blank lines in the file in gvim for windows (not vim from cygwin).
:g/^$/d # delete all blank lines correctly
:%s/^$//g #can not delete all blank lines
It's a problem how to express the end of line ,
i have checked my file in detail with the command %!xxd ,
i found there is a 0d0a at the end of every line,
when the end of line is expressed by the special character $ ,
does it contain the 0d0a?
it is different to express concept of the end of line betwwen command g and s ?
:%s/^$\n//g #delete all blank lines correctly
It confused me that ^$ will contain the special character \r\n or not,maybe ^$ in s command do not contai the special character \r\n ,but ^$ in g command do contai the special character \r\n.
which position does special character $ point at ? behind the \r\n or before the \r\n.
回答1:
No, the two commands are doing different things. :g/^$/d says "find empty lines and delete them", while :s/^$//g means "in this (current) line, replace all occurences of nothing-on-a-line with nothing (still on the same line)". The latter, as you notice, does not make sense.
EDIT for your edit:
The ^$ do not contain anything. It literally says "start of line, then immediately end of line", where "line" is detected by Vim. Vim knows that \r\n or \r or \n (depending on file and on which OS it was created, and on Vim's options) mark the end of line, and treats it accordingly. The separator lies between the ^$.
It's like when you say "the rooms in my house" - this (for me at least) does not include walls. When you say ^$\n, you're saying "the empty room, and also the wooden wall next to it". s/^$// is "empty the (already empty) room"; s/^$\n// is "empty the empty room and break down its wall".
In contrast, for g, again it does not say anything about \n. It finds the empty row (not caring about any separators), and then does a command on it; in your case, the command is d: delete a row. It deletes a full row (along with any newlines). For example, if you write :g/DELETEME/d, it would delete any rows that have DELETEME in it, anywhere: it does not care about any newlines in the match part, it just deletes the matched rows.
回答2:
d means delete the lines that are matched. s is just a substitution. Essentially the second expression means "substitute lines that match ^$ with an empty string," but that does not delete them. You are substituting nothing with nothing. ^ and $ are zero-width assertions and cannot be replaced.
回答3:
Both @Amadan and @Explosion Pills are right, but I think you really need an explanation of "how vim thinks" about what you are editing.
For one thing, vim is based on vi, which was a front end to the ex editor. Although vim has come a long way, it is still a line-based editor. Do not look for the magic character at the end of the line, because there is none! (When I say that vim has come a long way, I remember when the 'whichwrap' option was added.)
We usually do not bother to make the distinction, but the file on your hard disk is different from the buffer that you edit in vim (:help buffers). The file is a sequence of characters (or bytes). When vim reads the file, it splits them up into lines depending on the 'fileformat' option (short form 'ff'). Since you work on windows, the default is 'ff'=dos, which means that 0d0a (a.k.a. CRLF or \r\n) in the file is used to separate lines. I have 'ff'=unix, so I see only 0a when I filter through xxd. (Before OS X, Mac used 0d, so there were three standards!)
It is a good thing that the magical EOL character is simply not there, because that makes vim portable between systems. Being a line-based editor, vim lets you do all sorts of things like find the first pattern match on each line and do something to it. That is not always what you want, so some people get in the habit of adding /g at the end of every :s command, or even set 'gdefault'.
Coming back to your original question, removing a line from the buffer is very different from removing all the characters in the line. Ex commands (Remember the lineage) act on lines, and :d is the command to delete one. The :s command will change a line; do not be confused by the common usage :%s, which invokes :s on every line in the buffer (:help :range).
来源:https://stackoverflow.com/questions/21104783/why-s-g-is-not-equal-to-g-d-in-vim