3

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.

  • 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 '16 at 10:00
  • Are you asking how to know what exactly your pattern is matching in the file? – Antony Jul 22 '16 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 '16 at 11:51
  • Yes, and they should be distinct. – Lerner Zhang Jul 22 '16 at 11:58
4

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}
  • I've tried but it's not that effective as expected. – Lerner Zhang Sep 5 '16 at 7:57
  • What you mean with not that effective as expected? – Christian Brabandt Sep 5 '16 at 11:53
  • I want to know if there is a command to get the unique matches in a particular register? Thanks. – Lerner Zhang Sep 6 '16 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. – Christian Brabandt Sep 6 '16 at 6:38
  • Could you please tell me how I can print the b:types to a file? – Lerner Zhang Mar 26 '17 at 3:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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