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

I want to extract elements between " and ) & ) and ;; {or extract parameter and variables} from the given file

input.txt "BR")old_file="ods.csv" newfile="ods_nt_$curr_date.csv" newwack="rac_client_$curr_date.ack" IN_DIR="odc\5060" ;; "CL")old_file="ods_cash.csv" newfile="ods_nt_cash_acc_$curr_date.csv" newwack="rac_cash_acc_$curr_date.ack" IN_DIR="obc\5060" ;; "CUA")old_file="ods_ven.csv" newfile="ods_nt_ven_$curr_date.csv" newwack="rac_vendor_$curr_date.ack" IN_DIR="ofc\5060" ;; ##########################

OUTPUT should be : BR old_file="ods.csv" BR newfile="ods_nt_$curr_date.csv" BR newwack="rac_client_$curr_date.ack" BR IN_DIR="odc\5060" CL old_file="ods_cash.csv" CL newfile="ods_nt_cash_acc_$curr_date.csv" CL newwack="rac_cash_acc_$curr_date.ack" CL IN_DIR="obc\5060" CUA old_file="ods_ven.csv" CUA newfile="ods_nt_ven_$curr_date.csv" CUA newwack="rac_vendor_$curr_date.ack" CUA IN_DIR="ofc\5060"

please provide me solution. my code is given below which is not working properly.

open(data,"<input.txt"); while(<data>) { $line=<data>; if ($line=~/\"(.*)\)/) { $parameter=$1; } elsif (/\)/../\;\;/) { next if /\)/||/\;\;/; $var=$_; } print "$parameter. $var\n"; } close data;

Replies are listed 'Best First'.
Re: Extract content between two special character which is in single line or another line
by choroba (Cardinal) on Sep 26, 2016 at 11:50 UTC
    Here's how I'd do it: $parameter is defined if we are inside a block we want to process, undefined otherwise. $is_first_block just prevents a newline before the first block:

    #!/usr/bin/perl use warnings; use strict; my $is_first_block = 1; my $parameter; while (<>) { if (/^ \s* " ( [^"]+ ) " \)/x) { $parameter = $1; print "\n" unless $is_first_block; undef $is_first_block; } elsif (/;;/) { undef $parameter; } if (defined $parameter && /(\w+=.*)/) { my $var = $1; print "$parameter\t$var\n"; } }

    ($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,

      thank you chobara

Re: Extract content between two special character which is in single line or another line
by hippo (Archbishop) on Sep 26, 2016 at 14:14 UTC
    my code is given below which is not working properly.

    Since you've not given any idea of how it is "not working properly", here is the output of running your code as it stands:

    . newwack="rac_client_$curr_date.ack" CL". newwack="rac_client_$curr_date.ack" CL". newfile="ods_nt_cash_acc_$curr_date.csv" CL". IN_DIR="obc\5060" CL". newwack="rac_vendor_$curr_date.ack"

    The problems with it seem to include:

    • A failure to handle newlines
    • Capture of some unwanted double-quotes
    • Use of concatenation operator inside quotes
    • An if-elsif construct where the branches should not be mutually exclusive
    • A double-read from the input filehandle for each loop iteration

    Fixing these issues, using indentation and simplifying the logic gives us:

    open (data, "<input.txt"); while (<data>) { if (/"(.*)"\)(.*)$/) { $parameter = $1; $var = $2 . "\n"; } else { $var = $_; } if (/;;/) { print "\n"; next; } print "$parameter $var"; } close data;

    which produces this output:

    BR old_file="ods.csv" BR newfile="ods_nt_$curr_date.csv" BR newwack="rac_client_$curr_date.ack" BR IN_DIR="odc\5060" CL old_file="ods_cash.csv" CL newfile="ods_nt_cash_acc_$curr_date.csv" CL newwack="rac_cash_acc_$curr_date.ack" CL IN_DIR="obc\5060" CUA old_file="ods_ven.csv" CUA newfile="ods_nt_ven_$curr_date.csv" CUA newwack="rac_vendor_$curr_date.ack" CUA IN_DIR="ofc\5060"

    Formatting of the whitespace, compatibility with strict, conversion to 3-argument open, etc. are all left as an exercise (so you at least have some things still to do on your own).

      Thank you for your solution. it helped me

      Hi MOnks,

      I want to extract elements behind first ) & between ) and ;; {or extract parameter and variables}

      from the given and for the nested case file (or repeat the process if any case is coming)

      I need two type of solution : 1.using simple code 2.using subroutine

      Previously you explained me well . I tried to modify your code for next level. I need your help

      input.txt abhi) old_file="ak.csv" datefile="ak_nt_$curr_date.csv" cat /aksin/nil; cat /home/null case `kumar` in dbk) newwack="rac_client_$curr_date.ack" IN_DIR="class/5060" ;; src) src_folder="class/5061" ;; esac echo "$date_file" ;; bill)old_file="abh_cash.csv" date_file="ods_nt_cash_acc_$curr_date.csv" newwack="rac_cash_acc_$curr_date.ack" IN_DIR="xyx\5060" ;; payu) old_file="ods_ven.csv" newfile="ods_nt_ven_$curr_date.csv" newwack="rac_vendor_$curr_date.ack" IN_DIR="ofc\5060" case para in bcc) newreck="client_$curr_simul.ack" IN_DIR="class/5062" ;; src1) src_folder="class/5061" ;; esac ;; ##########################

      OUTPUT should be : abhi: old_file="ak.csv" abhi: datefile="ak_nt_$curr_date.csv" abhi:dbk: newwack="rac_client_$curr_date.ack" abhi:dbk: IN_DIR="class/5060" abhi:src: src_folder="class/5061" bill: old_file="abh_cash.csv" bill: date_file="ods_nt_cash_acc_$curr_date.csv" bill: newwack="rac_cash_acc_$curr_date.ack" bill: IN_DIR="xyx\5060" payu: old_file="ods_ven.csv" payu: newfile="ods_nt_ven_$curr_date.csv" payu: newwack="rac_vendor_$curr_date.ack" payu: IN_DIR="gunda\5060" payu:bcc: newreck="client_$curr_simul.ack" payu:bcc: IN_DIR="class/5062" payu:src1: src_folder="class/5061"

      I am not getting desired out put

      MY code is given below

      open (data, "<input.txt"); while (<data>) { s/^\s+//g; #LTRIM if (/"(.*)"\)(.*)$/) { #pattern match $parameter = $1; $var = $2 . "\n"; } else { $var = $_; } if (/case/../esac/){ if (/"(.*)"\)(.*)$/) { $parameter ="$parameter:$1"; $var = $2 . "\n"; } } if (/;;/) { print "\n"; next; } if($var=~/^\s*$/) {next;} #if $var is empty or 1 or more than 1 + whitespaces. elsif ($var!~/=/) {next;} #ignore if $var does not consist "=" +sign else{ print "$parameter: $var"; } } close data;