G+_Armand Hendriks Posted August 24, 2015 Share Posted August 24, 2015 Hi all. I have the following challenge and chose Perl to complete it. After going through the Perl module on Coding 101 that gave me my basis I came up with the following solution but still have some challenges and would appreciate some assistance or any guidance on what or how to do it: Problem: We have a csv file with thousands of records and I need to take the csv and convert them into ldif format for import. The common way the csv looks like is --> Fullname -->mobile -->email -->username -->password -->dealerCode I took this data and converted it to ldif but now there is a full name and I need the surname part of this field for each record so I used split for the initial version of the script and adding this into an array and then using the variables as needed but this does not compensate for people who has more than one name or a surname that has two parts. My question for your consideration is: How can I split up the Fullname but at the same time know when a surname starts vs the fullnames... I am unavailable to share the code.pl file for you but will paste it into this box. Thank you for any aid or suggestions. #-------------------------------------------------------------------------------------------------------------------# # Version 1.00 # # This schript is to take a csv file and convert it to ldif format # dependant on the requirement please ensure the csv is in the format as shown in code below else output will # be wrong, current format of csv is: # - First field: FullName # - Second field: Mobile number # - Third field: Email address # - Fourth field: UserName # - Fith field: Password # - Sixth field: Dealer Code # # If the csv is not in the exact same order as shown above the output will be incorrect and code must be adapted # to accomodate the new format. #-------------------------------------------------------------------------------------------------------------------# use FileHandle; #use the filehandle class to handle external files for processing. my(@details);#Declare the arrays # User will be asked for what file to be converted $csvFile = &promptUser("Name of file to be converted from CSV to LDIF 'Add' File"); $inputfile = new FileHandle($csvFile) || die "Can't open the import file!\n"; $outfile = new FileHandle(">$csvFile.ldif") || die "Can't create or open the output file!\n"; $logfile = new FileHandle(">AddData.log") || die "Can't create or open the log file!\n"; print $outfile "version: 1\n\n"; #First entry will be version 1 of ldif # Loop to run through the entire file of enteries by line to convert them to ldif format my $linecount = 0; while(my $line = <$inputfile>) { $linecount++; chomp($line); @details= split(',', $line); #Breakup the csv line to store values in an array # The below is taking the array and storing it in variables to be used as the loop executes $fullName = $details[0]; $mobile = $details[1]; $email = $details[2]; $userName = $details[3]; $password = $details[4]; $dealerCode = $details[5]; $cn = $userName; my @sn= split ('_', $fullName); #The actual format of how the ldif output for each entery will look like in the exported file print $outfile "dn: cn=$cn,cn=thirdPartyUsers,dc=enterprise,dc=mtn,dc=co,dc=za\n"; print $outfile "objectclass: person\n"; print $outfile "objectclass: top\n"; print $outfile "objectclass: organizationalPerson\n"; print $outfile "objectclass: orclUserV2\n"; print $outfile "objectclass: inetOrgPerson\n"; print $outfile "cn: $cn\n"; print $outfile "sn: $sn[1] $sn[2] $sn[3]\n"; print $outfile "givenname: $sn[0]\n"; print $outfile "mail: $email\n"; print $outfile "mobile: $mobile\n"; print $outfile "uid: $userName\n"; print $outfile "userpassword: $password\n"; print $outfile "\n"; } sub promptUser { #-----------------------------------------------------------------# # two possible input arguments - $promptString, and $defaultValue # # make the input arguments local variables. # #-----------------------------------------------------------------# local($promptString,$defaultValue) =@_; #-----------------------------------------------------------------# # if there is a default value, use the first print statement; if # # no default is provided, print the second string. # #-----------------------------------------------------------------# if ($defaultValue) { print $promptString, "[", $defaultValue, "]: "; } else { print $promptString, ": "; } $| = 1; # force a flush after our print $_ = ; # get the input from STDIN (presumably the keyboard) #----------------------------------------------------------------# # remove the newline character from the end of the input the user # # gave us. # #----------------------------------------------------------------# chomp; #---------------------------------------------------------------# # if we had a $default value, and the user gave us input, then # # return the input; if we had a default, and they gave us no # # no input, return the $defaultValue. # # # # if we did not have a default value, then just return whatever # # the user gave us. if they just hit the key, # # the calling routine will have to deal with that. # #---------------------------------------------------------------# if ("$defaultValue") { return $_ ? $_ : $defaultValue; # return $_ if it has a value } else { return $_; } } Link to comment Share on other sites More sharing options...
G+_Jeff Brand Posted August 25, 2015 Share Posted August 25, 2015 For readability in the future, try using a public pastebin or GitHub gists. Here's one for your code: https://gist.github.com/deltafactory/ff90a945d8bd6ebced02 Is the split() on line 55 extracting the surname? If so, could you count the number of elements in the resulting array to determine whether or not one is present? A less elegant solution would be to hardcode the list of possible surnames and detect them in the fullname field but that depends how clean the source data is. Link to comment Share on other sites More sharing options...
G+_Chris Bickhaus Posted August 25, 2015 Share Posted August 25, 2015 Does Perl support string slicing like Python? If so, I would search the string for the right-most space and then set your surname variable to a slice of the full name string beginning after the last space. This should work as most multiple part surnames, I think, are separated by hyphens. You could split the full name string based on spaces as well and just use the string in your list of split objects with the highest index. In Python this is index -1, so no need to know how many names there are. If Perl does not have that shorthand, could you reverse the list and then just use the first element? Or perhaps, you could use a while loop cutting off the first element of the list until there is only one left. That would be leave you with the last name. Again, it you split based on spaces, I would think that would still allow you to catch multi part last names, assuming hyphenation. Sorry, I cannot offer any Perl specific advice. Hope this helps. Link to comment Share on other sites More sharing options...
Recommended Posts