http://www.perlmonks.org?node_id=1009229


in reply to Re^2: looping logic error while printing output from folder/flie content
in thread looping logic error while printing output from folder/flie content

No Graff. I still not able to slove the problem but saying that I corrected container tags. Thank you very much

I don't know how to pass the correct subdirlevel1 and subdirlevel2 when the file found.

I have 3 files in each subdir levels and in all 1st container tag i get the values of subdirelevel1(MIUY) and in 2nd container tag i get the value as filename but not the folder name

Test file content which resides under A2/MIUY/CCT/CCT023.bat:

start putty -ssh -P 29921 1000.24008.50004.20CoioipreA -l root -pw olp.ikmj

Test file content which resides under A2/MIUY/SST/RETEEY.bat

start putty -ssh -P 278721A 10098.298748.509984.200901DukectreirecotA -l root -pw Tuytt.nA

Test file content which resides under A2/MIUY/WMW/WMWMTTY.bat

start putty -ssh -P 2210908A 1009.248090.50904.20001WyhgbvdserMipopA -l root -pw uyyn.npkju1A

Main script :

#!/usr/bin/perl use warnings; use strict; use File::Find; use File::Basename; my $base_dir = 'C:\Testdata'; # put in your base directory my ($dirname,$filename,$line,$resultfile,@fp,$file,$basedir1,$subdirle +vel1,$subdirlevel2); my (@linecolumns,@dir_names,@file,@filenames,@filecount); open ($resultfile, '>>', 'C:\Results\resultfile.txt') or die "Can' +t open file: $!"; print $resultfile '<?xml version="1.0" encoding="utf-8"?>'; print $resultfile "\n<!-- ********************-->\n"; print $resultfile "<!-- * *-->\n"; print $resultfile "<!-PuTTY Configuration Manager save file-All ri +ght reserved->\n"; print $resultfile "<!-- * *-->\n"; print $resultfile "<!-- *******************-->\n"; print $resultfile "<!-The following lines can be modified at your +own risks->\n"; opendir(IMD, $base_dir) || die("Cannot open directory"); my @thefiles= readdir(IMD); next if @thefiles eq '.' or @thefiles eq '..'; push(@thefiles, basename($base_dir)); #print $thefiles[2]; closedir(IMD); print $resultfile <<TTX <configuration version="0.1.1.2" savepassword="True"> <root type="database" name="$thefiles[2]" expanded="True"> TTX ; find( \&wanted, $base_dir ); print $resultfile "</root>\n"; print $resultfile "</configuration>\n"; sub wanted { return if $_ eq '.' or $_ eq '..'; if (-d) { print " >>> dive into: $_\n" if -d; $dirname = $_; push(@dir_names, basename($_)); } else { $basedir1 = $dir_names[0]; readout_file($_); ## call subroutine readout_file &write_output($_);## call subroutine to print std template in +output file print "Output file has been generated successfully.. \n"; } }

Sub functions

#sub function to write input file data into csv format sub readout_file { ($filename) = @_; open my $fh, '<', $filename or die "can't open file:$!"; while (<$fh>) { chomp; s/ /,/g; ## OR s/ /,/g; if you want @linecolumns=split(',',$_); $filename =~ s/.*\///; $filename =~ s/\.[^.]+$//; push(@filenames, $filename); } foreach(@dir_names){ (my $name,my $dir,my $ext) = fileparse($dir_names[1],'\..*'); $subdirlevel1 = $name; $filename =~ s/.*\///; $filename =~ s/\.[^.]+$//; $subdirlevel2=(basename($filename)); print $dir_names[3], $/; } } #sub function to write xml format in output file sub write_output{ print $resultfile <<EOF <container type="folder" name="$subdirlevel1" expanded="True"> <container type="folder" name="$subdirlevel2" expanded="T +rue"> <connection type="PuTTY" name="$filename"> <connection_info> <name>$filename</name> <protocol>SSH</protocol> <host>$linecolumns[5]</host> <port>$linecolumns[4]</port> <session>Default Settings</session> <commandline>$linecolumns[10]</commandline> <description /> </connection_info> <login> </login> <password /> <prompt /> <login> </login> <timeout> <connectiontimeout>1000</connectiontimeout> <logintimeout>750</logintimeout> <passwordtimeout>750</passwordtimeout> <commandtimeout>750</commandtimeout> </timeout> <command> <command1 /> <command2 /> <command3 /> <command4 /> <command5 /> </command> <options> <loginmacro>False</loginmacro> <postcommands>False</postcommands> <endlinechar>10</endlinechar> </options> </connection> </container> </container> EOF ; }

output :

<?xml version="1.0" encoding="utf-8"?> <!-- ***********************************************--> <!-- * *--> <!-PuTTY Configuration Manager save file-All right reserved-> <!-- * *--> <!-- ************************************************--> <!-The following lines can be modified at your own risks-> <configuration version="0.1.1.2" savepassword="True"> <root type="database" name="A2" expanded="True"> <container type="folder" name="MIUY" expanded="True"> ### fir +st time getting correct subdirlevel2 name <container type="folder" name="CCT023" expanded="True"> +######## need to get foldername CCT not filename <connection type="PuTTY" name="CCT023"> <connection_info> <name>CCT023</name> <protocol>SSH</protocol> <host>1000.24008.50004.20CoioipreA</host> <port>29921</port> <session>Default Settings</session> <commandline></commandline> <description /> </connection_info> <login> </login> <password /> <prompt /> <login> </login> <timeout> <connectiontimeout>1000</connectiontimeout> <logintimeout>750</logintimeout> <passwordtimeout>750</passwordtimeout> <commandtimeout>750</commandtimeout> </timeout> <command> <command1 /> <command2 /> <command3 /> <command4 /> <command5 /> </command> <options> <loginmacro>False</loginmacro> <postcommands>False</postcommands> <endlinechar>10</endlinechar> </options> </connection> </container> </container> <container type="folder" name="MIUY" expanded="True"> ###### N +o need to print this line again <container type="folder" name="RETEEYY" expanded="True"> +######### Need to get correct subdirlevel name which SST <connection type="PuTTY" name="RETEEYY"> <connection_info> <name>RETEEYY</name> <protocol>SSH</protocol> <host>10098.298748.509984.200901DukectreirecotA< +/host> <port>278721A</port> <session>Default Settings</session> <commandline></commandline> <description /> </connection_info> <login> </login> <password /> <prompt /> <login> </login> <timeout> <connectiontimeout>1000</connectiontimeout> <logintimeout>750</logintimeout> <passwordtimeout>750</passwordtimeout> <commandtimeout>750</commandtimeout> </timeout> <command> <command1 /> <command2 /> <command3 /> <command4 /> <command5 /> </command> <options> <loginmacro>False</loginmacro> <postcommands>False</postcommands> <endlinechar>10</endlinechar> </options> </connection> </container> ####################### not required </container> <container type="folder" name="MIUY" expanded="True"> ###### N +o need to print this line again <container type="folder" name="WMWMTTY" expanded="True"># +######## Need to get correct subdirlevel name which WMW <connection type="PuTTY" name="WMWMTTY"> <connection_info> <name>WMWMTTY</name> <protocol>SSH</protocol> <host>1009.248090.50904.20001WyhgbvdserMipopA</h +ost> <port>2210908A</port> <session>Default Settings</session> <commandline></commandline> <description /> </connection_info> <login> </login> <password /> <prompt /> <login> </login> <timeout> <connectiontimeout>1000</connectiontimeout> <logintimeout>750</logintimeout> <passwordtimeout>750</passwordtimeout> <commandtimeout>750</commandtimeout> </timeout> <command> <command1 /> <command2 /> <command3 /> <command4 /> <command5 /> </command> <options> <loginmacro>False</loginmacro> <postcommands>False</postcommands> <endlinechar>10</endlinechar> </options> </connection> </container>########################## Not need </container> </root> </configuration>

Replies are listed 'Best First'.
Re^4: looping logic error while printing output from folder/flie content
by graff (Chancellor) on Dec 18, 2012 at 08:19 UTC
    Regarding the comments you placed in your output (which were very helpful):
    ... <container type="folder" name="CCT023" expanded="True"> ######## nee +d to get foldername CCT not filename ...
    (and likewise for the other two input files). This is happening because you are using the variable "$subdirlevel2" which is being set to the file name (minus the extension); you should set that to the appropriate directory name instead.
    ... </container> ####################### not required </container> ...
    Your comment there is incorrect. You have opened two "container" tags, one nested inside the other, so you need to close tags, one after the other, to complete the structure.

    Have you tried stepping through your code with the perl debugger? If you haven't learned to use the debugger yet, it's time to learn now. It's really very simple. (The full man page for it is here: perldebug, but you might want to start with perldebtut.) Set a breakpoint in your subroutines, and step through the lines of code in each one, checking the values that get assigned to variables, and what the various modules and functions are returning.

    Also, take a closer look at how the sample code I suggested in my earlier reply is handling the information made available by File::Find. Read the man page for File::Basename more carefully. You might also need to consider what will happen when your program has to cover a different pattern of directory nesting.

      Thanks Graff. Now I have installed pkdb module after reading the point which you said in pervious reply and I can do the debugging line by line.

      On this point : "You might also need to consider what will happen when your program has to cover a different pattern of directory nesting."

      Even i was thinking this, what ever i tried to script is now only for pre defined set of directory structure, which is very wrong way. Can you please advise how can make script more generic one so that don't need to depend on directory pattern

      Many Thanks
        The code I posted above is one way to handle variation in the directory structure. You might need to tweak it to get the kind of xml layout that you want.
        A reply falls below the community's threshold of quality. You may see it by logging in.