0

I'm looking for a shortcut for loading back-reference groups using the same separator. Such a beast may not exist but it would be useful to me if it does. An example:

Starting with this string

:111 222 333 444 555

applying this pattern

:%s/\(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\)/\5 \4 \3 \2 \1/g

will give me this result

:555 444 333 222 111

What I'm looking for is something to replace the match,

:\(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\)

by giving it a pattern and a separator, and have it load as many groups as match.

::%s/<"\(\d\+\) ">/\5 \4 \3 \2 \1/g

Is there a way to do this? Thanks!

1 Answer 1

2

Many ways to do it!

Awk

$ awk '{for(i=1;i<=NF/2;i++) { t = $(NF-i+1); $(NF-i+1) = $i; $i = t; } print}' inpout.txt > output.txt

Prettier version of awk program:

{
    for (i=1; i<=NF/2; i++) {
        t = $(NF-i+1);
        $(NF-i+1) = $i;
        $i = t;
    }
    print
}

From inside Vim using filter, :!:

:%!awk '{for(i=1;i<=NF/2;i++) { t = $(NF-i+1); $(NF-i+1) = $i; $i = t; } print}'

Perl

From: Swapping an unlimited number of columns:

:%!perl -lane 'print join " ", reverse @F'

Pure Vim:

Use split(), join(), and reverse() to parse & reverse each line.

:g/^/call setline('.', join(reverse(split(getline("."), ' ')), " "))

For more help see:

:h :g
:h :call
:h setline()
:h getline()
:h join()
:h reverse()
:h split()

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.