count occurrences and substitute with counter

Hi Unix-Experts,

I have a textfile with several occurrences of some string XXX. I'd like to count all the occurrences and number them in reverse order.

E.g. input: XXX bla XXX foo XXX
output: 3 bla 2 foo 1

I tried to achieve this with sed, but failed. Any suggestions?

Thanks in advance!!

Tobias

awk '{ c = NF-1; for (i=1; i<=NF; i++)
$i = i == NF ? $i : $i (OFS = $1 ? OFS : "") c--
}1' FS="XXX" filename

Use nawk or /usr/xpg4/bin awk on Solaris.

Hi radoulov, thanks for the really quick reply. I just tried your suggestion, but it just gives
input: XXX bla XXX foo XXX
output: 1 bla 1 foo 1

...I guess the problem is that I'm not talking about the XXX being on a single line, but spread over the whole textfile!

Is this also possible with awk? Remember - I dunno the number of occurences of XXX in advance! :confused:

I understand, if the file is not too big:

awk '{ c = NF-1; for (i=1; i<=NF; i++)
$i = i == NF ? $i : $i (OFS = $1 ? OFS : "") c--
}1' FS="XXX" RS= filename

P.S. Because some Awk distributions cannot handle
large records you can use perl, this is the output from a2p
(I'm quite new to perl, so I still don't want to post my own version :)):

#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
    if $running_under_some_shell;
                        # this emulates #! processing on NIH machines.
                        # (remove #! line above if indigestible)

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
                        # process any FOO=bar switches

$[ = 1;                 # set array base to 1
$FS = ' ';              # set field separator
$, = ' ';               # set output field separator
$\ = "\n";              # set output record separator

$FS = 'XXX';
$/ = "\n\n";

while (<>) {
    chomp;      # strip record separator
    @Fld = split($FS, $_, -1);
    $c = $#Fld - 1;
    for ($i = 1; $i <= $#Fld; $i++) {
        $Fld[$i] = $i == $#Fld ? $Fld[$i] : $Fld[$i] . ($, = $Fld[1] ? $,

          : '') . $c--;
    }
    print join($,,@Fld);
}