root@progress.COM (Root of all Evil) (04/24/91)
Is there any way within ex (or some other text processing utility) to access the nth occurrence of a pattern? What I'd like to do is search a file for the nth occurrence of a pattern and then change that pattern but no others. I've tried using ex: ex -s FILE << QUIT /STRING1/n s/STRING1/STRING2/ wq! QUIT but this only places me n lines after the first occurrence of STRING1. Any ideas? I'd like to avoid writing to a temporary file. Thanks... Rich P.S. I use the Bourne shell. ------------------------------------------------------------------------------ Rich Lenihan UUCP: mit-eddie!progress!rich Progress Software Corp. Internet: rich@progress.com 5 Oak Park >- Insert funny stuff here -< Bedford, MA 01730 >-Draw amusing symbols, logo's-< USA >- or characters here -<
subbarao@phoenix.Princeton.EDU (Kartik Subbarao) (04/24/91)
In article <1991Apr23.180034.7349@progress.com> root@progress.COM (Root of all Evil) writes: > >Is there any way within ex (or some other text processing utility) to >access the nth occurrence of a pattern? What I'd like to do is search >a file for the nth occurrence of a pattern and then change that pattern >but no others. I've tried using ex: > >ex -s FILE << QUIT >/STRING1/n s/STRING1/STRING2/ >wq! >QUIT If you have perl, you can say this: % perl -pi -e 'if (/STRING1/) { s/STRING1/STRING2/ if (++$num == N); }' FILE Isn't perl cool :-) -Kartik -- internet# rm `df | tail +2 | awk '{ printf "%s/quotas\n",$6}'` subbarao@phoenix.Princeton.EDU -| Internet kartik@silvertone.Princeton.EDU (NeXT mail) SUBBARAO@PUCC.BITNET - Bitnet
merlyn@iwarp.intel.com (Randal L. Schwartz) (04/24/91)
In article <1991Apr23.180034.7349@progress.com>, root@progress (Root of all Evil) writes: | Is there any way within ex (or some other text processing utility) to | access the nth occurrence of a pattern? What I'd like to do is search | a file for the nth occurrence of a pattern and then change that pattern | but no others. I've tried using ex: | | ex -s FILE << QUIT | /STRING1/n s/STRING1/STRING2/ | wq! | QUIT | | but this only places me n lines after the first occurrence of STRING1. | Any ideas? I'd like to avoid writing to a temporary file. perl -pe '/STRING1/ && (++$n == 20) && s/STRING1/STRING2/' <in >out OK, so the syntax is cryptic; do it C-like if you want: perl -pe 'if (/STRING1/ && (++$n == 20)) { s/STRING1/STRING2/; }' <in >out or even (more verbosely): perl -pe 'if (/STRING1/) { s/STRING1/STRING2/ if ++$n == 20; }' <in >out (well, maybe not more verbosely, then... :-) Or even: perl -pe 's/STRING1/STRING2/ if /STRING1/ && (++$n == 20);' <in >out All of these presume "20" is your magic occurance. Season to taste. print "Just another Perl hacker," # Perl is available from all GNU sites... -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/
root@ttsi.lonestar.org (System) (04/25/91)
In article <1991Apr23.215804.8366@iwarp.intel.com> merlyn@iwarp.intel.com (Randal L. Schwartz) writes: >In article <1991Apr23.180034.7349@progress.com>, root@progress (Root of all Evil) writes: >| Is there any way within ex (or some other text processing utility) to >| access the nth occurrence of a pattern? What I'd like to do is search >| a file for the nth occurrence of a pattern and then change that pattern >| but no others. I've tried using ex: >| >| ex -s FILE << QUIT >| /STRING1/n s/STRING1/STRING2/ >| wq! >| QUIT >| >| but this only places me n lines after the first occurrence of STRING1. >| Any ideas? I'd like to avoid writing to a temporary file. > >perl -pe '/STRING1/ && (++$n == 20) && s/STRING1/STRING2/' <in >out > >OK, so the syntax is cryptic; do it C-like if you want: > >perl -pe 'if (/STRING1/ && (++$n == 20)) { s/STRING1/STRING2/; }' <in >out > >or even (more verbosely): > >perl -pe 'if (/STRING1/) { s/STRING1/STRING2/ if ++$n == 20; }' <in >out > >(well, maybe not more verbosely, then... :-) Or even: > >perl -pe 's/STRING1/STRING2/ if /STRING1/ && (++$n == 20);' <in >out > >All of these presume "20" is your magic occurance. Season to taste. > >print "Just another Perl hacker," # Perl is available from all GNU sites... These all presume only one occurrence or first occurrence per line. Is that the requirement? How would you handle counting multiple occurrences per line in perl? Thanks for posting the solutions above. -- Mark S. Evans Tandem Telecommunications Systems Inc. Phone: 214-516-6201 850 E. Central Parkway Fax: 214-516-6801 Plano, TX 75074 Mail: mse@ttsi.lonestar.org
merlyn@iwarp.intel.com (Randal L. Schwartz) (04/26/91)
In article <1991Apr25.040751.1991@ttsi.lonestar.org>, root@ttsi (System) writes: | >perl -pe '/STRING1/ && (++$n == 20) && s/STRING1/STRING2/' <in >out | > | >perl -pe 'if (/STRING1/ && (++$n == 20)) { s/STRING1/STRING2/; }' <in >out | > | >perl -pe 'if (/STRING1/) { s/STRING1/STRING2/ if ++$n == 20; }' <in >out | > | >perl -pe 's/STRING1/STRING2/ if /STRING1/ && (++$n == 20);' <in >out | > | >All of these presume "20" is your magic occurance. Season to taste. | > | >print "Just another Perl hacker," # Perl is available from all GNU sites... | | These all presume only one occurrence or first occurrence per line. | Is that the requirement? How would you handle counting multiple | occurrences per line in perl? Thanks for posting the solutions above. OK, now you did it. You asked me to get ugly. Hang on to your hat... perl -pe 's/STRING1/(++$n == 20) ? "STRING2" : $&/ge' <in >out You might need to look at this one for a while to figure out what's happening. Trust me, it'll be good for you. :-) (And if you can't figure it out, I know this great book on the subject... :-) print "Just another Perl hacker,"; -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/