Self-follow-up:

I.

I've just realised I made a careless error in trying to literally
reproduce your careless mistake, even though it should have been
obvious this was incorrect or at least incomplete.  Instead of just

  :w !grep -c

clearly you meant:

  :w !grep -c abc

Though as noted before, that still won't count all same-line instances
and thus won't fit the bill.


II.

I *thought* I'd also now found another way to do this, and actually do
this with grep by using sed:

  :!sed s/abc/abc\n/g % | grep -c abc

However, I can't get the newline to work right in OpenBSD's sed.
It does work in GNU sed.

man sed has this:

> The escape sequence \n matches a newline character embedded in the pattern 
> space. You can't, however, use a literal newline character in an address or 
> in the substitute command.

Now I *thought* \n was NOT considered a literal newline, and that I
should thus be able to get this to work, but I'm a little stumped.

Googled information suggests that the opposite of what's described in
the man page may be true:  You CAN use a literal newline, but you
can't use \n.
But I'm not sure if the googled information is correct and I still
haven't figured this one out.

In trying to get this to work, I took a FILE that contains a bunch of
abc's, sometimes several to a line, sometimes not, and I did this[0]:

  $ sed s/abc/abc^M/g FILE > DAFTFILE

Here ^M *was supposed to be* a literal newline, i.e. I pressed ^V
followed by the return key, but readers more alert than me can
doubtlessly already see the problem:  Apparently ^V[enter] yields a
literal carriage return, not a literal newline (^J).  That's the case
on Linux as well, and I don't know why.

One interesting observation, if someone does get this to work, is that this
  :!sed s/abc/abc\n/g % | grep -c abc
is only shorter than this
  :!cat % | tr '\n' ' ' | awk '{print gsub(/abc/, "")}'
if the abc string is short.


III.

Your new subject line is slightly imprecise, as words are usually
whitespace-delimited, and I was "looking for a way to count
occurrences of
'abc' in FILE".  Not every substring is a word.


Thanks for your help,
Ian


Footnote:
[0] I redirected things to DAFTFILE here so I could use vi instead of
more misleading tools to look at the contents, because at some point
just echoing, catting or tailing the output didn't clearly show the
^M's, and it took a while for me to catch on to how they were a
problem.


On 04/09/2021, ropers <rop...@gmail.com> wrote:
> On 03/09/2021, Marc Chantreux <m...@unistra.fr> wrote:
>>> 'abc' in FILE, from within vi.
>>
>> * % means 'the current file' in vi commands so you can write
>
> That's helpful; thank you!
>
>> * | is the command separator
>> * grep has a -c flag to count occurrences
>>
>> so you can write:
>>
>>     :w|grep -c abc %
>
> That doesn't really fit the bill:
>
> 1. This error message is produced: 'The grep command is unknown'
>
> 2. grep only counts the number of lines.  If the 'abc' reappears in
> the same line, grep won't catch that.  My version will, however
> crufty, though it's arguably better/shorter/more portable to use your
> %:
>
>   :!cat % | tr '\n' ' ' | awk '{print gsub(/abc/, "")}'
>
> And yes, I did also try
>   :%!tr '\n' ' ' | awk '{print gsub(/abc/, "")}'
> but the problem with that is, it replaces the buffer with the number
> of occurrences.  So cat it is unless someone can point to something
> better.
>
>> you can also write the content of the buffer to a pipe (my prefered
>> solution here):
>>
>>     :w !grep -c
>
> That produces a grep usage prompt here, along with this message:
> 'grep -c: exited with status 2.'
> Are you sure you've tested this and that you're using just plain (n)vi?
> Also, again, grep -c, which I did know about, is insufficient for
> counting every occurrence.  I suspect there's prolly s/th better than
> my clumsy kludge, but grep -c is not de wey.
>
>>> Sadly, :E doesn't actually work in vim.  It says
>>> > E464: Ambiguous use of user-defined command
>>
>>> I don't know what works in vim. vim prolly has a dozen
>>> chrome-electroplated ways to do the same thing, but I don't know them.
>>
>> :h windows
>>
>> also:
>>
>> :h :new
>> :h :enew
>> :h gf
>> :h :bu
>> :h :ls
>> :h :bw
>>
>> the following code isfrom my ~/.vimrc so i can:
>>  * navigate into buffers with <left> and <right> arrows
>>  * come back to the first buffer with <down>
>>  * have a fzf menu of the current buffers using <up>
>>
>> set hidden
>> command! -nargs=0 BU redir! > ~/.v.json | silent echo
>> json_encode(getbufinfo()) | redir END
>>   \| silent exec "!vim_BU ~/.v.json ~/.v"
>>   \|so ~/.v
>>   \|redraw!
>> nnoremap <up>     <esc>:BU<cr>
>> nnoremap <down>  :bfirst!<cr>
>> nnoremap <left>  :bnext!<cr>
>> nnoremap <right> :bprevious!<cr>
>>
>> the code of vim_BU (i can probably get grid of perl and use jq instead):
>>
>> vim_BU () {
>>      perl -MEnv -MJSON -w0 -nE'
>>              map +( printf "%3s %s%s %s\n"
>>                      , $$_{bufnr}
>>                      , ( $$_{hidden}       ? "h"       : "a" )
>>                      , ( $$_{changed}      ? "+"       : " " )
>>                      , ( length $$_{name}  ? $$_{name} : "NONAME" )
>>              ), @{ decode_json $_ }
>>      ' $1 | fzf | awk '{print "bu "$1}' > $2
>> }
>
> Wow, that's... helpful(?), I think, but truth be told, I've tested
> none of this, because I'm slightly overwhelmed by what to me looks
> like far greater complexity than :E, ^W etc. -- and even than my
> occurrence-counting one-liner.
>
> Maybe I'm just not truly ready for vim (though I do use it at times).
>
>> regards
>> marc
>
> None of the above is intended as throwing anything back in your face
> however, and I thank you very much for your reply.
>
> Kind regards,
> Ian
>
> PS: Regarding this:
>> get grid[sic] of perl and use jq
> Presumably that's <https://stedolan.github.io/jq/>?
> Honestly, I hadn't even heard of jq.
> It's not in base; I do see it's in ports, but it's not installed on
> any OpenBSD machines I've ever had access to.  I see jq is acceptably
> licensed, but so long as perl is in base and jq isn't... it makes more
> sense for me to learn perl than jq.  Because I'm not great with perl
> either, but still.
>

Reply via email to