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

Hi all,

I would like to know if there is a way of outputting multiple commands to an output file, without it getting all scrambled. I have code that is supposed to write three commands to an output file. The code as follows:

sub CreateLoadFile { open LOADCREATE print LOADCREATE $CreateViewCmd; print LOADCREATE $ChangeDirectory; print LOADCREATE $LoadViewCmd; }

The close of the file happens after this component. The result of the output is fine if there is only one record in the input file.

However, if there is more than one record, the output is bunched together. The first output command will appear x times on the output file, and then the second output command x times and then the third output command x times. How can I change this so that the three commands is bunched together for one input redord?

Edit: g0n - added code & p tags

Replies are listed 'Best First'.
Re: Multiple command prints in same output file
by davidrw (Prior) on Jul 08, 2005 at 09:54 UTC
    can you post more (and working -- that open statement is incomplete and missing a ';') code? Especially how you're reading the input file and taking that data (presumably setting the $CreateViewCmd, $ChangeDirectory, and $LoadViewCmd variables) and your loop structures.
      Here is the complete piece of code:

      #!/usr/bin/perl -w $DescribeFile = $ARGV[0]; $ComponentFile = $ARGV[1]; $LoadCreateFile = ">".$ARGV[2]; # *** Process the data from the input file *** $Pause .= "pause\n"; &Main_Process; # *** Subroutine that does the main processing of program. *** sub Main_Process { $IntFound = 0; $RootFound = 0; &OpenProjectFile; foreach $_ (@DescribeData) { &ProcessGetViewInfo; } close LOADCREATE; } # *** Subroutine that Opens, reads and closes the input file * +** sub OpenProjectFile { open DESCRIBE, $DescribeFile or die "Can not find the project descri +be file!"; while (!eof(DESCRIBE)) { read DESCRIBE, $DescribeDataFromFile, 100; $DescribeData .= $DescribeDataFromFile; } close DESCRIBE; $DescribeData =~ s/\n\n/\n/g; @DescribeData = split("\n", $DescribeData); } # *** Subroutine that gets the required view info from the file + *** sub ProcessGetViewInfo { &FindTag; } # *** Subroutine that finds and stores the view tag name for the curen +t view *** sub FindTag { if (m/project "/) { $ProjectLine = $_; $PrjLeftQuote = index($ProjectLine, "t"); $NameLength = length($ProjectLine) - $PrjLeftQuote - 4; $ProjectName = substr($ProjectLine, $PrjLeftQuote + 3, $NameLength +); } if (m/integration stream:/) { $DescribeLine = $_; $LeftQuote = index($DescribeLine, ":"); $RightQuote = index($DescribeLine, "@"); $Intname = $RightQuote - $LeftQuote - 2; $Int = substr($DescribeLine, $LeftQuote + 2 , $Intname); $Int2 = substr($DescribeLine, $LeftQuote + 2 , length($DescribeLin +e)); $CreateViewCmd .= "cleartool mkview -snapshot -tag ".$Int."_Snapsh +ot -stream ".$Int2." -colocated_server -host idetestcc1 -hpath d:\\Cl +earCase_Storage\\views\\snapshot\\".$Int."_Snapshot -gpath d:\\ClearC +ase_Storage\\views\\snapshot\\".$Int."_Snapshot \\\\idetestcc1\\ccstg +_d\\views\\snapshot\\".$Int."_Snapshot\n"; $IntFound ++; &OpenComponentFile; foreach $_ (@ComponentData) { &ProcessComponent; } } } # *** Subroutine that Opens, reads and closes the input file * +** sub OpenComponentFile { open COMPONENT, $ComponentFile or die "Can not find the component fi +le!"; while (!eof(COMPONENT)) { read COMPONENT, $CompDataFromFile, 100; $ComponentData .= $CompDataFromFile; } close COMPONENT; $ComponentData =~ s/\n\n/\n/g; @ComponentData = split("\n", $ComponentData); } # *** Subroutine that gets the required view info from the file + *** sub ProcessComponent { &FindRoot; if ($RootFound == 1) { &CreateLoadFile; } } # *** Subroutine that finds and stores the root name for the current p +roject *** sub FindRoot { if (m/$ProjectName/) { if (m/root directory:/) { $RootLine = $_; $LeftQuoteRoot = index($RootLine, ":"); $RightQuoteRoot = length($RootLine) - $LeftQuoteRoot - 4; $Root = substr($RootLine, $LeftQuoteRoot + 3, $RightQuoteRoot); $LoadViewCmd .= "cleartool update -add_loadrules \.".$Root." \n +"; $D .= "d:\n"; $ChangeDirectory .= "cd clearcase_storage\\views\\snapshot\\".$ +Int."_Snapshot\n"; $RootFound ++; } } } # *** Subroutine that opens and prints the load spec file +*** sub CreateLoadFile { open LOADCREATE, $LoadCreateFile or die "Can not find the LoadCreate +File!"; print LOADCREATE $CreateViewCmd; print LOADCREATE $D; print LOADCREATE $ChangeDirectory; print LOADCREATE $LoadViewCmd; print LOADCREATE $Pause; $RootFound = 0; }

      Hope this helps!

        first comment is use strict (among other things this will complain about the undeclared global variable $RootFound) .. after that, I'm confused as to why $LoadCreateFile is opened for writing and _clobbered_ each time.. that will result in just 1 set of print's ever being in there..

        (i meant to ask earlier) could you post a sample of the output you're currently getting and a sample of the desired output?
Re: Multiple command prints in same output file
by bofh_of_oz (Hermit) on Jul 08, 2005 at 15:19 UTC
    Just a few suggestions...

    - First, let me support others in strongly encouraging you to use strict... That should lead you to a much clearer view on how your code is working (as opposed to how it supposed to work). Writing a program without properly declaring variables can lead to all sorts of interesting though unpredictable behaviour (not to mention that the code then looks very VB-ish...)

    - I am kinda puzzled that you can get any data at all, as your @DescribeData is not in the scope of Main_Process, where you parse its values... just as @ComponentData is not defined in the scope of FindTag.

    - I believe that it would be clearer if you just passed $_ as an argument to ProcessGetViewInfo instead of letting Perl decide how it might wanna do it... It might work as desired but then again, it might not.

    - Try making your functions return values instead of using (variables declared in those functions) outside the functions. That way, you can write:

    &CreateLoadFile if &FindRoot;
    instead of declaring $RootFound in FindRoot() and use it in the function that calls FindRoot...

    Hope this helps to figure out where the problem is and fix it...

     

    P.S. Oh, and also try to insert print statement(s) just before you call CreateLoadFile. Use it to print the values of the variables you are printing to the file... When you see it in the console, you might get a better idea of what's going on...

    --------------------------------
    An idea is not responsible for the people who believe in it...