These two are not really the same. In your example,
:g/./ normal!I" will only prepend non-empty lines with a
", but it will not prepend the
" to empty lines, which the
:%normal!I" will do.
:g always needs a pattern and only acts on the lines that match that pattern. If you use an empty pattern (
//), Vim will reuse the last pattern you used in a previous search,
A closer similar to the
% range would be using
:g/^/, which is a pattern that will match all lines, including empty ones.
:g will have other side effects not in
%, since when you use a pattern it is then saved as the last used pattern, which also presents itself visually if you have
Also note that
:g itself takes a range! You can use
:10,20g/pattern/command to execute the command only on lines between 10 and 20 which also match the passed pattern. In fact,
:g/^/ normal!I" is equivalent to
:%g/^/ normal!I". In other words,
:g defaults to the
% range when one is not passed explicitly.
% range is exactly equivalent to
:1,$, the range of lines between the first and the last one in the buffer.