2

Tried this with vim, but open to other ideas/suggestions.

Would like to perform a search and replace in a file with 12000 lines.

Specifically, if an occurrence of "^ SetFontSize 28" exists after a "^Hide" definition and before the next "^Hide" or "^Show", change 28 to 18. Example below.

Here's a snippet from the original file.

Hide # Gear - Endgame
    ItemLevel >= 77
    Rarity = Magic
    LinkedSockets >= 3
    BaseType "Runic Hatchet"
    SetTextColor 140 190 255 # Magic Item Highlight
    SetFontSize 28

Hide # Gear - Endgame
    ItemLevel >= 77
    Rarity = Magic
    Sockets >= 3
    BaseType "Runic Hatchet"
    SetTextColor 140 190 255 # Magic Item Highlight
    SetFontSize 28

Show # Gear - Endgame
    ItemLevel >= 83
    Rarity = Normal
    Sockets < 3
    BaseType "Tiger Hook"
    SetTextColor 240 240 240 # Normal Item Highlight
    SetBackgroundColor 70 70 70
    SetFontSize 28

The end result for the first "Hide" block would look like this:

Hide # Gear - Endgame
    ItemLevel >= 77
    Rarity = Magic
    LinkedSockets >= 3
    BaseType "Runic Hatchet"
    SetTextColor 140 190 255 # Magic Item Highlight
    SetFontSize 18

Replacing SetFontSize 28 to SetFontSize 18, but only if it appears in a "^Hide" block.

The nasty regex I tried in vim: :%s/^Hide\(.*\)SetFontSize 28$/Hide\1SetFontSize 18/g

But was told pattern not found. Please let me know if any additional information is required or if my request is unclear.

2

Just two corrections:

  • In Vim's regexp, . does not include newlines. Probably there is some better way, but I usually just do (.|[\n]) when I need that.
  • * is greedy, but you want non-greedy matching here. {-} does the trick.

And one more thing, which is my personal preference, so take it for what it's worth: I had hard time remembering what is magic character in Vim's regexp, and what is not; so I ended up just using \v in the beginning of the pattern, so that all ASCII characters except '0'-'9', 'a'-'z', 'A'-'Z' and '_' have a special meaning.

All in all:

%s/\v^Hide((.|[\n]){-})SetFontSize 28/Hide\1SetFontSize 18/g

  • This works, but it's bleeding over into the next block. For example, if you look at the snippet in the original, there are 3 blocks. I want to edit the 2 blocks labeled "Hide" but leave the "Show" block unmodified. For some reason, every "Show" block after a "Hide" block also has the SetFontSize changed from 28 to 18. The change should only occur on the "Hide" blocks. Ideas? – Guy Feb 20 '16 at 19:17
  • Ok, so I just tried your suggestion in the snippet, and it works perfectly, leaving the "Show" block unedited. But when additional Show/Hide blocks are added (just copy/paste the blocks, doubling it to 6 or 12, etc), it's doing the behavior described above. Editing the Hide blocks, but also the Show block right underneath a Hide block. – Guy Feb 20 '16 at 19:30
  • When I copy paste the original snippet and add more Show/Hide blocks, :set hlsearch on, it's highlighting the Hide blocks correctly using the first half of the find/replace you provided. But when I copy/paste the entire recommendation, they're all highlighted, Show and Hide. That's odd... Here's the file I'm editing in it's entirety. Again, just want all the "Hide" blocks with SetFontSize 28 changed to SetFontSize 18. clbin.com/Fbr10 – Guy Feb 20 '16 at 19:39
  • Update. Got it working with this... :%s/^Hide\(\(.\+\n\)\{-}.*\)SetFontSize 28/Hide\1SetFontSize 18/g – Guy Feb 20 '16 at 21:43
  • \_. is like . but matches newlines. See: :help /\_. – Heptite Feb 21 '16 at 0:41

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.