Reputation: 2401
I do not know if that title will sound adequate …
Let us say I have a file (> 1000 lines) with a homogeneous structure throughout consisting of three "fields" separated by a space :
1. an integer (negative or positive)
<space>
2. another integer (negative or positive)
<space>
3. some text (description)
The integers are >-10000 and < 10000
My problem is : how can I
a) filter this file with criteria such as "1st integer <= 1000" AND "2nd integer >=250" AND "text contains : Boston OR New-York"
b) and put the subset in a new buffer, allowing me to read the results and only the results of the filter(s) ?
I wish to do that with Vim only, not knowing if it is feasible or reasonable (anyway it is above my skills)
Thanks
@FDinoff : sorry, I should have done what you suggest, of course :
It could be a chronology with a StartDate, an EndDate, and a Description :
1 -200 -50 Period one in Italy
2 -150 250 Period one in Greece
3 -50 40 Period two in Italy
4 10 10 Some event in Italy
5 20 20 Event two in Greece
The filter could be : Filter the items where (to mimic SQL) StartDate <=-50 AND EndDate >=0 AND Description contains Greece, with a resulting filter => line 2
Upvotes: 0
Views: 291
Reputation: 5746
The following generic form will match the numeric parts of your format:
^\s*-\?\d\+\s\+-\?\d\+
To implement restrictions on the numbers, replace each -\?\d\+
with a more specific pattern. For example, for <= -50
:
-\([5-9][0-9]\|[1-9][0-9]\{2,}\)
That is, -
followed by either a 2 digit number where the first digit is >= 5, or a >= 3 digit number.
Similarly, for >= 250
:
\(2[5-9][0-9]\|[3-9][0-9]\{2,}\)
Combining the two:
^\s*-\([5-9][0-9]\|[1-9][0-9]\{2,}\)\s\+\(2[5-9][0-9]\|[3-9][0-9]\{2,}\)
If you also need to filter by some pattern in the description, append that:
^\s*-\([5-9][0-9]\|[1-9][0-9]\{2,}\)\s\+\(2[5-9][0-9]\|[3-9][0-9]\{2,}\)\s\+.\{-}Greece
.\{-}
is the lazy version of .*
.
To filter by this pattern and write the output to a file, use the following:
:g/pattern/.w filename
Thus, to filter by "first number <= -50 AND second number >= 250 AND 'Greece' in description" and write the output to greece.out
:
:g/^\s*-\([5-9][0-9]\|[1-9][0-9]\{2,}\)\s\+\(2[5-9][0-9]\|[3-9][0-9]\{2,}\)\s\+.\{-}Greece/.w greece.out
More complex ranges quickly make this even more ridiculous; you're probably better off parsing the file and filtering with something other than regex.
Upvotes: 1