Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

How can I replace the pattern in the 6 th field?

by theravadamonk (Scribe)
on Jun 18, 2018 at 15:23 UTC ( [id://1216862]=perlquestion: print w/replies, xml ) Need Help??

theravadamonk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl Monks,

I have DATA like this

__DATA__ Jun 12 09 mail (sender@sender.com) - (recip1@domain.com) 0.075 9387 Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@domai +n.com) -1.889 25623

How can I replace the pattern ( and ) in the 6 th field?

The OUTPUT I expect is

__DATA__ Jun 12 09 mail (sender@sender.com) - recip1@domain.com 0.075 9387 Jun 12 10 mail (sender@sender.com) - recip1@domain.com,recip2@domain.c +om -1.889 25623

the below code replaces all fields.

$_ =~ s/\(|\)//g;

Can I have something like this?

$_ =~ s/\(|\)//$f[6]g;

Your Ideas? Pls help me to slove this.

Replies are listed 'Best First'.
Re: How can I replace the pattern in the 6 th field?
by choroba (Cardinal) on Jun 18, 2018 at 15:33 UTC
    Count the brackets, start replacing from the third one:
    #!/usr/bin/perl use warnings; use strict; while (<DATA>) { my $c = 0; s/([()])/$c++ > 1 ? "" : $1/ge; print } __DATA__ Jun 12 09 mail (sender@sender.com) - (recip1@domain.com) 0.075 9387 Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@domai +n.com) -1.889 25623

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Hi, Thanks for your prompt reply. My ACTUAL data has more than that. Since data is sensitive I did NOT want to post everything. anyway, This is my DATA. sir, Pls forgive me.

      __DATA__ Jun 12 09 mail (sender@sender.com) - (recip1@domain.com) 0.075 9387, q +ueued_as: C77837C0050 Subject goes here Sender(sender@sender.com) Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@domai +n.com) -1.889 25623, queued_as: B67837C0052 Subject goes here Sender( +sender@sender.com)

      Pls look at the last field. I don't want to replace last filed. Is there a way to capture ONLY 6 the field?

      waiting for your inputs.

        OK, then use split and run the substitution on the seventh (the dash is a field, too) field only:
        while (<DATA>) { chomp; my @F = split / /; $F[6] =~ s/[()]//g; say join ' ', @F; }
        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        If whitespace actually is the field delimiter, another way to operate on only the seventh field of the entire record without first extracting all fields would be this (needs Perl version 5.14+):

        c:\@Work\Perl\monks>perl -wMstrict -le "use 5.014; ;; my $rec = 'Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@d +omain.com) -1.889 25623, queued_as: B67837C0052 Subject goes here Sen +der(sender@sender.com)'; print qq{'$rec'}; ;; $rec =~ s{ \A \s* (?: \S+ \s+){6} \K (\S+) }{ $1 =~ tr/()//dr }xmse; print qq{'$rec'}; " 'Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@doma +in.com) -1.889 25623, queued_as: B67837C0052 Subject goes here Sender +(sender@sender.com)' 'Jun 12 10 mail (sender@sender.com) - recip1@domain.com,recip2@domain. +com -1.889 25623, queued_as: B67837C0052 Subject goes here Sender(sen +der@sender.com)'
        Whether this is faster/better than a split/join approach is left as an exercise for theravadamonk; I doubt it really is. (This approach requires Perl version 5.14+ due to use of the  /r modifier in the  tr/// operator and version 5.10+ for the  \K regex operator. These can be avoided in earlier versions of Perl fairly simply; let me know if a workaround is needed. (Update: See this reply for workarounds.))


        Give a man a fish:  <%-{-{-{-<

        You could split on the dash and run the substitution operator on the second field.
Re: How can I replace the pattern in the 6 th field?
by jwkrahn (Abbot) on Jun 18, 2018 at 18:23 UTC
    $ echo "Jun 12 09 mail (sender@sender.com) - (recip1@domain.com) 0.075 + 9387 Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@domai +n.com) -1.889 25623" | perl -pe's/(?:\S+\s+){6}\K(.+)/($x=$1)=~tr,(), +,d;$x/e' Jun 12 09 mail (sender@sender.com) - recip1@domain.com 0.075 9387 Jun 12 10 mail (sender@sender.com) - recip1@domain.com,recip2@domain.c +om -1.889 25623
      s/(?:\S+\s+){6}\K(.+)/($x=$1)=~tr,(),,d;$x/e

      This removes the dependence on Perl version 5.14 for the  /r modifier for the  tr/// operator, but does not satisfy the latest approximation to the real spec as given here. (Don'tcha just love receiving specs via drip-feed?) The problem is easily fixed with a  (\S+) vice  (.+) capture (still requires Perl version 5.10+):

      c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; print 'perl version: ', $]; ;; my $rec = 'Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@d +omain.com) -1.889 25623, queued_as: B67837C0052 Subject goes here Sen +der(sender@sender.com )'; print qq{'$rec'}; ;; $rec =~ s/(?:\S+\s+){6}\K(\S+)/(my $x=$1)=~tr,(),,d;$x/e; print qq{'$rec'}; " perl version: 5.010001 'Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@doma +in.com) -1.889 25623, queued_as: B67837C0052 Subject goes here Sender +(sender@sender.com)' 'Jun 12 10 mail (sender@sender.com) - recip1@domain.com,recip2@domain. +com -1.889 25623, queued_as: B67837C0052 Subject goes here Sender(sen +der@sender.com)'
      That still leaves a dependence on version 5.10 for the  \K regex operator, again easily fixed with another capture:
      c:\@Work\Perl\monks>perl -wMstrict -le "print 'perl version: ', $]; ;; my $rec = 'Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@d +omain.com) -1.889 25623, queued_as: B67837C0052 Subject goes here Sen +der(sender@sender.com)'; print qq{'$rec'}; ;; $rec =~ s/((?:\S+\s+){6})(\S+)/(my $x=$2)=~tr,(),,d;$1.$x/e; print qq{'$rec'}; " perl version: 5.008009 'Jun 12 10 mail (sender@sender.com) - (recip1@domain.com),(recip2@doma +in.com) -1.889 25623, queued_as: B67837C0052 Subject goes here Sender +(sender@sender.com)' 'Jun 12 10 mail (sender@sender.com) - recip1@domain.com,recip2@domain. +com -1.889 25623, queued_as: B67837C0052 Subject goes here Sender(sen +der@sender.com)'


      Give a man a fish:  <%-{-{-{-<

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1216862]
Approved by haukex
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (8)
As of 2024-03-28 09:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found