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

Hi Monks, I'm struggling with the task of capturing a date value that is populated in column 8 of a pipe delimited file and inserting it into column 11.

row|1|CUSIP|12345678|RED|||20150125|||| row|1|CUSIP|1234A82H|RED|||20150316||||

for the 2 examples above the final result should be:

row|1|CUSIP|12345678|RED|||20150125|||20150125| row|1|CUSIP|1234A82H|RED|||20150316|||20150316|

I know i need to use memory parens to capture the value in column 8, but can't seem to get it to work

perl -pi -e 's/\(RED|||([0-9]{8})|||\)/\1/g'

The above is what i have so far.

Thanks for any suggestions

Replies are listed 'Best First'.
Re: one liner to capture value of field and insert in another field
by choroba (Cardinal) on Jan 28, 2015 at 15:33 UTC
    perl -i~ -F'\|' -lane 'print join "|", @F[0..9], $F[7], ""'

    -F specifies the separator.
    -a populates the @F array with the cell values for each row.
    -l handles the newlines.

    See perlrun for the details.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: one liner to capture value of field and insert in another field
by Anonymous Monk on Jan 28, 2015 at 15:35 UTC
    pipe (|) is special in regular expressions. And you shouldn't use \1 in right hand side of s///. In fact, you shouldn't use s/// at all. split is what you need.
    $ perl -F'\|' -lane '$F[10] = $F[7]; print join "|", @F' file.txt row|1|CUSIP|12345678|RED|||20150125|||20150125| row|1|CUSIP|1234A82H|RED|||20150316|||20150316|
    (see perlrun for details)

      Works like a charm. Thanks you!

      (choroba, great minds think alike! :)

      I guess i jumped the gun a little bit. My apologies. It works for the sample i provided, but the real file has almost 300 fields in each record..some of those values are populated and some aren't...so simply joining a "|" at the end doesn't work for the actual file.

      is there a way to do what you did but instead of Joining one pipe at the end can we somehow join the remaining ~300 col values to each record?

      row|1|CUSIP|35472T200|ARDIV|||20150112|||||||||||||||||||||||||||||||| +|||||||||||||||||||||20150321||||||G||||||||||||||||||||FR||||||||||| +||||||||||||||||||||||||||||||||||||X|||||||||||||||||||||||||||||||| +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +||||||||||||||||||||||||||||||||||||||||LIQ|||||||||||||||||||||||||| +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +||||||||||||

      Sorry for the incomplete data and thx again.

        The problem with split is that by default, trailing empty fields are discarded. You can specify a negative count to prevent that, but you need to be more explicit in such a case:
        perl -lne '@F = split /\|/, $_, -1; $F[10] = $F[7] ; print join "|", +@F'
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
        You mean the records are spread out across several lines? And what separates them?