5

I have a very large file containing about, for example, 5 million lines like this:

Songs=****, Singers=****
Singers=***
Songs=***
.... # many many lines
SongType=***
... # many many lines again
Album=***, Singers=**

Since all characters replaced by * are Chinese characters I use /[a-zA-Z]*= to match "Songs", "Singers". And I don't know if I've matched the third: "SongType" since I cannot see it using my eyes, let alone the fourth: "Album".

The problem is that: can I use a vague pattern, in my case [a-zA-Z]*= to know all distinct possibilities(of the same pattern)? I mean all the four strings here.

Of course I can use g command to delete all that matched and see those left. But what if the fifth and others are so rare that I cannot pick them out in the left lines? And in this way the "Album" is deleted and I can never find it.

I have tried to first copy all matched strings to a register and then sort u it in an other file to check, but failed because of the register limitation.

4
  • 1
    The problem is that the file is too large and contains may not only these three type and I want to check all the matched distinctions. I'm not really sure I understand the question. Do you want to search for different strings in the same pattern as nobe4 showed you or are you trying to do something else?
    – statox
    Jul 22, 2016 at 10:00
  • Are you asking how to know what exactly your pattern is matching in the file?
    – Antony
    Jul 22, 2016 at 11:38
  • Ok I think I understand: You want to get in one place all the strings matching the pattern [a-zA-Z]*= right? I think your idea of putting it all in a register was good what was your limitation?
    – statox
    Jul 22, 2016 at 11:51
  • Yes, and they should be distinct. Jul 22, 2016 at 11:58

1 Answer 1

6

You can do it like this:

:let b:types=[]
:%s/[A-Za-z]*\>/\=add(b:types, submatch(0))/ng
:echo uniq(b:types)

This searches for the pattern /[A-Za-z]*\> and adds the result to the List variable b:types. Since we are only interested in the adding the matches to the list, and don't want to change the buffer, we use the n flag to the :s command. The g flag is there, to get all matches.

Now this will populate your list with all matches, so since we are only interested in the uniq entries, we run the uniq() function on the result again.

Note, the uniq() function is only available with a Vim 7.4.500 or so, so it is relative recent.

If you are further interested in the statistics, you can do it like this:

function! Count(match)
  if has_key(b:types, a:match)
      let b:types[a:match]+=1
  else
      let b:types[a:match]=1
  endif
  return a:match
endfu
let b:types={}
%s/[A-Za-z]*\>/\=Count(submatch(0))/gn
echo b:types

This will count each match. The output of the b:types variable might look like this:

{'SongType': 1, 'Songs': 2, 'Singers': 3, 'Album': 1}
6
  • I've tried but it's not that effective as expected. Sep 5, 2016 at 7:57
  • What you mean with not that effective as expected? Sep 5, 2016 at 11:53
  • I want to know if there is a command to get the unique matches in a particular register? Thanks. Sep 6, 2016 at 6:17
  • Well, your question did not mention that you want to use specifically registers for that, but you can of course use a register instead of a variable in the first solution I mentioned. Sep 6, 2016 at 6:38
  • Could you please tell me how I can print the b:types to a file? Mar 26, 2017 at 3:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.