1 #!/usr/bin/perl -w 2 # 3 # $RCSfile: MergeTextFiles.pl,v $ 4 # $Date: 2008/01/30 21:44:48 $ 5 # $Revision: 1.24 $ 6 # 7 # Author: Manish Sud <msud@san.rr.com> 8 # 9 # Copyright (C) 2004-2008 Manish Sud. All rights reserved. 10 # 11 # This file is part of MayaChemTools. 12 # 13 # MayaChemTools is free software; you can redistribute it and/or modify it under 14 # the terms of the GNU Lesser General Public License as published by the Free 15 # Software Foundation; either version 3 of the License, or (at your option) any 16 # later version. 17 # 18 # MayaChemTools is distributed in the hope that it will be useful, but without 19 # any warranty; without even the implied warranty of merchantability of fitness 20 # for a particular purpose. See the GNU Lesser General Public License for more 21 # details. 22 # 23 # You should have received a copy of the GNU Lesser General Public License 24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or 25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, 26 # Boston, MA, 02111-1307, USA. 27 # 28 29 use 5.006; 30 use strict; 31 use FindBin; use lib "$FindBin::Bin/../lib"; 32 use Getopt::Long; 33 use File::Basename; 34 use Text::ParseWords; 35 use Benchmark; 36 use FileHandle; 37 use SDFileUtil; 38 use FileUtil; 39 use TextUtil; 40 41 my($ScriptName, %Options, $StartTime, $EndTime, $TotalTime); 42 my($TextFile, @TextFilesList, $NewTextFile, $Index, $FileDir, $FileName, $FileExt, $InDelim, $OutDelim, $OutQuote, $Line, @ColValues, @KeyValues, @ColLabels, $ColLabel, $ColNum, $ColIndex, $Values, @Words, @LineWords); 43 44 # Autoflush STDOUT 45 $| = 1; 46 47 # Starting message... 48 $ScriptName = basename $0; 49 print "\n$ScriptName:Starting...\n\n"; 50 $StartTime = new Benchmark; 51 52 # Get the options and setup script... 53 SetupScriptUsage(); 54 if ($Options{help} || @ARGV < 1) { 55 die GetUsageFromPod("$FindBin::Bin/$ScriptName"); 56 } 57 @TextFilesList = ExpandFileNames(\@ARGV, "csv tsv"); 58 59 if (@TextFilesList == 1) { 60 die "Error: Specify more than one Text file.\n"; 61 } 62 63 if ($Options{root}) { 64 $FileDir = ""; $FileName = ""; $FileExt = ""; 65 ($FileDir, $FileName, $FileExt) = ParseFileName($Options{root}); 66 if ($FileName && $FileExt) { 67 $NewTextFile = $FileName; 68 } 69 else { 70 $NewTextFile = $Options{root}; 71 } 72 } 73 else { 74 $FileDir = ""; $FileName = ""; $FileExt = ""; 75 ($FileDir, $FileName, $FileExt) = ParseFileName($TextFilesList[0]); 76 $NewTextFile = $FileName . "1To" . @TextFilesList . "Merged"; 77 } 78 if ($Options{outdelim} =~ /^tab$/i) { 79 $NewTextFile .= ".tsv"; 80 } 81 else { 82 $NewTextFile .= ".csv"; 83 } 84 if (!$Options{overwrite}) { 85 if (-e $NewTextFile) { 86 die "Error: The file $NewTextFile already exists.\n"; 87 } 88 } 89 if ($Options{root}) { 90 for $Index (0 .. $#TextFilesList) { 91 if (lc($NewTextFile) eq lc($TextFilesList[$Index])) { 92 die "Error: Output filename, $NewTextFile, is similar to a input file name.\nSpecify a different name using \"-r --root\" option or use default name.\n"; 93 } 94 } 95 } 96 if ($Options{columns}) { 97 @ColValues = split ";", $Options{columns}; 98 if (@ColValues != @TextFilesList) { 99 die "Error: Invalid number of values specified by \"-c --columns\" option: it must be equal to number of input text files.\n"; 100 } 101 for $Index (0 .. $#ColValues) { 102 if (!length($ColValues[$Index])) { 103 die "Error: Invalid value specified by \"-c --columns\" option: empty values are not allowed.\n"; 104 } 105 } 106 } 107 if ($Options{keys}) { 108 @KeyValues = split ";", $Options{keys}; 109 if (@KeyValues != @TextFilesList) { 110 die "Error: Invalid number of values specified by \"-k --keys\" option: it must be equal to number of input text files.\n"; 111 } 112 for $Index (0 .. $#KeyValues) { 113 if (!length($KeyValues[$Index])) { 114 die "Error: Invalid value specified by \"-k --keys\" option: empty values are not allowed.\n"; 115 } 116 } 117 } 118 print "Processing various options and checking input text files...\n"; 119 120 # Collect column information for all the text files... 121 my(@TextFilesColCount, @TextFilesInDelim, @TextFilesColLabels, @TextFilesColLabelToNumMap); 122 RetrieveTextFilesInfo(); 123 124 # Collect values specified using "-c --columns" option and map 'em to colnum... 125 my(@TextFilesColSpecified, @TextFilesColToMerge, @TextFilesColToMergeNumToLabelMap); 126 ProcessColumnsOption(); 127 128 # Collect values specified using "-k --keys" option and map 'em to colnum... 129 my(@TextFilesKeysSpecified, @TextFilesKeysToUse, $Key); 130 if ($Options{keys}) { 131 ProcessKeysOption(); 132 } 133 134 # Get the column used for stating merge in the first text file. 135 my(@File1Part1ColNums, @File1Part2ColNums); 136 ProcessStartColOption(); 137 138 print "Generating new Text file $NewTextFile...\n"; 139 140 open NEWTEXTFILE, ">$NewTextFile" or die "Error: Couldn't open $NewTextFile: $! \n"; 141 142 #Write out column labels for the merged text file... 143 @ColLabels = (); 144 145 #Collect column labels from first file before the merge point... 146 for $ColNum (@File1Part1ColNums) { 147 push @ColLabels, $TextFilesColToMergeNumToLabelMap[0]{$ColNum}; 148 } 149 #Collect column labels from other text files... 150 for $Index (1 .. $#TextFilesList) { 151 for $ColNum (@{$TextFilesColToMerge[$Index]}) { 152 push @ColLabels, $TextFilesColToMergeNumToLabelMap[$Index]{$ColNum}; 153 } 154 } 155 #Collect column labels from first file after the merge point... 156 for $ColNum (@File1Part2ColNums) { 157 push @ColLabels, $TextFilesColToMergeNumToLabelMap[0]{$ColNum}; 158 } 159 #Write it out... 160 $Line = JoinWords(\@ColLabels, $OutDelim, $OutQuote); 161 print NEWTEXTFILE "$Line\n"; 162 163 #Open up all the files and skip label line... 164 my(@TextFilesHandleList) = (); 165 for $Index (0 .. $#TextFilesList) { 166 $TextFilesHandleList[$Index] = new FileHandle; 167 $TextFile = $TextFilesList[$Index]; 168 open $TextFilesHandleList[$Index], "$TextFile" or die "Error: Couldn't open $TextFile: $! \n"; 169 $Line = GetTextLine($TextFilesHandleList[$Index]); 170 } 171 if ($Options{keys}) { 172 MergeColumnValuesUsingKeys(); 173 } 174 else { 175 MergeColumnValues(); 176 } 177 #close up all the files... 178 close NEWTEXTFILE; 179 for $Index (0 .. $#TextFilesList) { 180 close $TextFilesHandleList[$Index]; 181 } 182 print "$ScriptName:Done...\n\n"; 183 184 $EndTime = new Benchmark; 185 $TotalTime = timediff ($EndTime, $StartTime); 186 print "Total time: ", timestr($TotalTime), "\n"; 187 188 ############################################################################### 189 190 #Merger all the column values... 191 sub MergeColumnValues { 192 my(@File1LineWords, $Value); 193 while ($Line = GetTextLine($TextFilesHandleList[0])) { 194 $InDelim = $TextFilesInDelim[0]; 195 @ColValues = (); 196 #Collect column values from first file before the merge point... 197 @File1LineWords = quotewords($InDelim, 0, $Line); 198 for $ColNum (@File1Part1ColNums) { 199 $Value = ($ColNum < @File1LineWords) ? $File1LineWords[$ColNum] : ""; 200 push @ColValues, $Value; 201 } 202 #Collect column values from other text files... 203 for $Index (1 .. $#TextFilesList) { 204 $InDelim = $TextFilesInDelim[$Index]; 205 if ($Line = GetTextLine($TextFilesHandleList[$Index])) { 206 @LineWords = quotewords($InDelim, 0, $Line); 207 for $ColNum (@{$TextFilesColToMerge[$Index]}) { 208 $Value = ($ColNum < @LineWords) ? $LineWords[$ColNum] : ""; 209 push @ColValues, $Value; 210 } 211 } 212 } 213 #Collect column labels from first file after the merge point... 214 for $ColNum (@File1Part2ColNums) { 215 $Value = ($ColNum < @File1LineWords) ? $File1LineWords[$ColNum] : ""; 216 push @ColValues, $Value; 217 } 218 # Write it out... 219 $Line = JoinWords(\@ColValues, $OutDelim, $OutQuote); 220 print NEWTEXTFILE "$Line\n"; 221 } 222 } 223 224 # Merge column values using keys... 225 sub MergeColumnValuesUsingKeys { 226 my(@File1LineWords, $Value, $KeyColNum, $KeyColValue, @TextFilesKeysToLinesMap); 227 228 @TextFilesKeysToLinesMap = (); 229 # Retrieve text lines from all the files except for the first file... 230 for $Index (1 .. $#TextFilesList) { 231 $InDelim = $TextFilesInDelim[$Index]; 232 %{$TextFilesKeysToLinesMap[$Index]} = (); 233 $KeyColNum = $TextFilesKeysToUse[$Index]; 234 while ($Line = GetTextLine($TextFilesHandleList[$Index])) { 235 @LineWords = quotewords($InDelim, 0, $Line); 236 if ($KeyColNum < @LineWords) { 237 $KeyColValue = $LineWords[$KeyColNum]; 238 if (length($KeyColValue)) { 239 if (exists($TextFilesKeysToLinesMap[$Index]{$KeyColValue})) { 240 warn "Warning: Ignoring line, $Line, in text file $TextFilesList[$Index]: Column key value, $KeyColValue, already exists\n"; 241 } 242 else { 243 @{$TextFilesKeysToLinesMap[$Index]{$KeyColValue}} = (); 244 push @{$TextFilesKeysToLinesMap[$Index]{$KeyColValue}}, @LineWords; 245 } 246 } 247 } 248 } 249 } 250 while ($Line = GetTextLine($TextFilesHandleList[0])) { 251 $InDelim = $TextFilesInDelim[0]; 252 @ColValues = (); 253 @File1LineWords = quotewords($InDelim, 0, $Line); 254 $KeyColNum = $TextFilesKeysToUse[0]; 255 $KeyColValue = $File1LineWords[$KeyColNum]; 256 257 #Collect column values from first file before the merge point... 258 for $ColNum (@File1Part1ColNums) { 259 $Value = ($ColNum < @File1LineWords) ? $File1LineWords[$ColNum] : ""; 260 push @ColValues, $Value; 261 } 262 #Collect column values from other text files... 263 for $Index (1 .. $#TextFilesList) { 264 @LineWords = (); 265 if (exists($TextFilesKeysToLinesMap[$Index]{$KeyColValue})) { 266 push @LineWords, @{$TextFilesKeysToLinesMap[$Index]{$KeyColValue}}; 267 } 268 for $ColNum (@{$TextFilesColToMerge[$Index]}) { 269 $Value = ($ColNum < @LineWords) ? $LineWords[$ColNum] : ""; 270 push @ColValues, $Value; 271 } 272 } 273 #Collect column labels from first file after the merge point... 274 for $ColNum (@File1Part2ColNums) { 275 $Value = ($ColNum < @File1LineWords) ? $File1LineWords[$ColNum] : ""; 276 push @ColValues, $Value; 277 } 278 # Write it out... 279 $Line = JoinWords(\@ColValues, $OutDelim, $OutQuote); 280 print NEWTEXTFILE "$Line\n"; 281 } 282 } 283 284 # Process specified columns... 285 sub ProcessColumnsOption { 286 my($SpecifiedColNum); 287 288 @TextFilesColSpecified = (); @TextFilesColToMerge = (); 289 @TextFilesColToMergeNumToLabelMap = (); 290 for $Index (0 .. $#TextFilesList) { 291 $Values = "all"; 292 if ($Options{columns}) { 293 $Values = $ColValues[$Index] 294 } 295 @{$TextFilesColSpecified[$Index]} = (); 296 if ($Values =~ /all/i) { 297 if ($Options{mode} =~ /^colnum$/i) { 298 for $ColNum (1 .. $TextFilesColCount[$Index]) { 299 push @{$TextFilesColSpecified[$Index]}, $ColNum; 300 } 301 } else { 302 push @{$TextFilesColSpecified[$Index]}, @{$TextFilesColLabels[$Index]}; 303 } 304 } else { 305 @Words = split ",", $Values; 306 push @{$TextFilesColSpecified[$Index]}, @Words; 307 } 308 @{$TextFilesColToMerge[$Index]} = (); 309 %{$TextFilesColToMergeNumToLabelMap[$Index]} = (); 310 if ($Options{mode} =~ /^collabel$/i) { 311 for $ColIndex (0 .. $#{$TextFilesColSpecified[$Index]}) { 312 $ColLabel = $TextFilesColSpecified[$Index][$ColIndex]; 313 if (exists($TextFilesColLabelToNumMap[$Index]{$ColLabel})) { 314 $ColNum = $TextFilesColLabelToNumMap[$Index]{$ColLabel}; 315 push @{$TextFilesColToMerge[$Index]}, $ColNum; 316 $TextFilesColToMergeNumToLabelMap[$Index]{$ColNum} = $ColLabel; 317 } else { 318 warn "Warning: Ignoring value, $ColLabel, specified using \"-c --column\" option: column name doesn't exist in $TextFilesList[$Index] \n"; 319 } 320 } 321 } else { 322 for $ColIndex (0 .. $#{$TextFilesColSpecified[$Index]}) { 323 $SpecifiedColNum = $TextFilesColSpecified[$Index][$ColIndex]; 324 if ($SpecifiedColNum > 0 && $SpecifiedColNum <= $TextFilesColCount[$Index]) { 325 $ColNum = $SpecifiedColNum - 1; 326 push @{$TextFilesColToMerge[$Index]}, $ColNum; 327 $TextFilesColToMergeNumToLabelMap[$Index]{$ColNum} = $TextFilesColLabels[$Index][$ColNum]; 328 } else { 329 warn "Warning: Ignoring value, $SpecifiedColNum, specified using \"-c --column\" option: column number doesn't exist in $TextFilesList[$Index] \n"; 330 } 331 } 332 } 333 my (@TextFilesColToMergeSorted) = sort @{$TextFilesColToMerge[$Index]}; 334 @{$TextFilesColToMerge[$Index]} = (); 335 push @{$TextFilesColToMerge[$Index]}, @TextFilesColToMergeSorted; 336 } 337 } 338 339 # Process specified key column values... 340 sub ProcessKeysOption { 341 @TextFilesKeysSpecified = (); @TextFilesKeysToUse = (); 342 for $Index (0 .. $#TextFilesList) { 343 $Key = $KeyValues[$Index]; 344 $TextFilesKeysSpecified[$Index] = $Key; 345 $TextFilesKeysToUse[$Index] = -1; 346 if ($Options{mode} =~ /^collabel$/i) { 347 $ColLabel = $Key; 348 if (exists($TextFilesColLabelToNumMap[$Index]{$ColLabel})) { 349 $TextFilesKeysToUse[$Index] = $TextFilesColLabelToNumMap[$Index]{$ColLabel}; 350 } else { 351 warn "Warning: Ignoring value, $ColLabel, specified using \"-k --keys\" option: column name doesn't exist in $TextFilesList[$Index] \n"; 352 } 353 } else { 354 $ColNum = $Key; 355 if ($ColNum > 0 && $ColNum <= $TextFilesColCount[$Index]) { 356 $TextFilesKeysToUse[$Index] = $ColNum - 1; 357 } else { 358 warn "Warning: Ignoring value, $ColNum, specified using \"-k --keys\" option: column number doesn't exist in $TextFilesList[$Index] \n"; 359 } 360 } 361 } 362 # Modify columns to merge list to make sure the columns identified by key are taken off the list 363 # except for the first text file... 364 my(@TextFilesColToMergeFiltered); 365 for $Index (1 .. $#TextFilesList) { 366 @TextFilesColToMergeFiltered = (); 367 for $ColNum (@{$TextFilesColToMerge[$Index]}) { 368 if ($TextFilesKeysToUse[$Index] != $ColNum) { 369 push @TextFilesColToMergeFiltered, $ColNum; 370 } 371 } 372 @{$TextFilesColToMerge[$Index]} = (); 373 push @{$TextFilesColToMerge[$Index]}, @TextFilesColToMergeFiltered; 374 } 375 } 376 377 # Process specified start column value... 378 sub ProcessStartColOption { 379 my($StartColNum, $Part1StartColNum, $Part1EndColNum, $Part2StartColNum, $Part2EndColNum, $BeforeStartColNum, $AfterStartColNum, $FirstColNum, $LastColNum, $FirstIndex, $LastIndex); 380 381 @File1Part1ColNums = (); @File1Part2ColNums = (); 382 $StartColNum = "last"; 383 if (exists($Options{startcol})) { 384 if (length($Options{startcol})) { 385 $StartColNum = $Options{startcol} 386 } 387 } 388 if ($StartColNum !~ /^last$/i) { 389 if ($Options{mode} =~ /^collabel$/i) { 390 if (exists($TextFilesColLabelToNumMap[0]{$StartColNum})) { 391 $StartColNum = $TextFilesColLabelToNumMap[0]{$StartColNum}; 392 } else { 393 die "Error: Invalid value $StartColNum specified using \"-s --startcol\" option: column name doesn't exist in $TextFilesList[0] \n"; 394 } 395 } else { 396 if ($StartColNum > 0 && $StartColNum <= $TextFilesColCount[0]) { 397 $StartColNum -= 1; 398 } else { 399 die "Error: Invalid value $StartColNum specified using \"-s --startcol\" option: column number doesn't exist in $TextFilesList[0] \n"; 400 } 401 } 402 } else { 403 $StartColNum = $TextFilesColCount[0] - 1; 404 } 405 406 # Make sure StartColNum is present on the list of columns to merge for the first text file... 407 if (!exists($TextFilesColToMergeNumToLabelMap[0]{$StartColNum})) { 408 die "Error: Invalid value $StartColNum specified using \"-s --startcol\" option: doesn't exist in the specified lists of columns to merge for $TextFilesList[0] \n"; 409 } 410 # Find out the column number before and after StartColNum in first text file... 411 $BeforeStartColNum = $StartColNum; 412 $AfterStartColNum = $StartColNum; 413 $FirstIndex = 0; $LastIndex = $#{$TextFilesColToMerge[0]}; 414 $FirstColNum = $TextFilesColToMerge[0][$FirstIndex]; 415 $LastColNum = $TextFilesColToMerge[0][$LastIndex]; 416 for $Index (0 .. $LastIndex) { 417 if ($TextFilesColToMerge[0][$Index] == $StartColNum) { 418 $BeforeStartColNum = (($Index -1) >= $FirstIndex) ? $TextFilesColToMerge[0][$Index - 1] : ($FirstColNum - 1); 419 $AfterStartColNum = (($Index + 1) <= $LastIndex) ? $TextFilesColToMerge[0][$Index + 1] : ($LastColNum + 1); 420 } 421 } 422 if ($Options{startcolmode} =~ /^after$/i) { 423 $Part1StartColNum = $FirstColNum; $Part1EndColNum = $StartColNum; 424 $Part2StartColNum = $AfterStartColNum; $Part2EndColNum = $LastColNum; 425 } 426 else { 427 $Part1StartColNum = $FirstColNum; $Part1EndColNum = $BeforeStartColNum; 428 $Part2StartColNum = $StartColNum; $Part2EndColNum = $LastColNum; 429 } 430 @File1Part1ColNums = (); @File1Part2ColNums = (); 431 for $ColIndex (0 .. $#{$TextFilesColToMerge[0]}) { 432 $ColNum = $TextFilesColToMerge[0][$ColIndex]; 433 if ($ColNum >= $Part1StartColNum && $ColNum <= $Part1EndColNum) { 434 push @File1Part1ColNums, $ColNum; 435 } 436 } 437 for $ColIndex (0 .. $#{$TextFilesColToMerge[0]}) { 438 $ColNum = $TextFilesColToMerge[0][$ColIndex]; 439 if ($ColNum >= $Part2StartColNum && $ColNum <= $Part2EndColNum) { 440 push @File1Part2ColNums, $ColNum; 441 } 442 } 443 } 444 445 # Retrieve information about input text files... 446 sub RetrieveTextFilesInfo { 447 my($TextFilesErrorCount) = 0; 448 449 @TextFilesColCount = (); @TextFilesInDelim = (); @TextFilesColLabels = (); 450 @TextFilesColLabelToNumMap = (); 451 FILELIST: for $Index (0 .. $#TextFilesList) { 452 $TextFile = $TextFilesList[$Index]; 453 $TextFilesColCount[$Index] = 0; 454 @{$TextFilesColLabels[$Index]} = (); 455 %{$TextFilesColLabelToNumMap[$Index]} = (); 456 if (!(-e $TextFile)) { 457 warn "Warning: File $TextFile doesn't exist\n"; 458 $TextFilesErrorCount++; 459 next FILELIST; 460 } 461 if (!CheckFileType($TextFile, "csv tsv")) { 462 warn "Warning: Problematic file $TextFile: It's not a csv or tsv file\n"; 463 $TextFilesErrorCount++; 464 next FILELIST; 465 } 466 ($FileDir, $FileName, $FileExt) = ParseFileName($TextFile); 467 if ($FileExt =~ /^tsv$/i) { 468 $InDelim = "\t"; 469 } 470 else { 471 $InDelim = "\,"; 472 if ($Options{indelim} !~ /^(comma|semicolon)$/i) { 473 warn "Warning: Ignoring file $TextFile: The value specified, $Options{indelim}, for option \"--indelim\" is not valid for csv files\n"; 474 $TextFilesErrorCount++; 475 next FILELIST; 476 } 477 if ($Options{indelim} =~ /^semicolon$/i) { 478 $InDelim = "\;"; 479 } 480 } 481 if (!open TEXTFILE, "$TextFile") { 482 warn "Warning: Problematic file $TextFile: Couldn't open it: $! \n"; 483 $TextFilesErrorCount++; 484 next FILELIST; 485 } 486 $Line = GetTextLine(\*TEXTFILE); 487 @ColLabels = quotewords($InDelim, 0, $Line); 488 $TextFilesInDelim[$Index] = $InDelim; 489 $TextFilesColCount[$Index] = @ColLabels; 490 push @{$TextFilesColLabels[$Index]}, @ColLabels; 491 for $ColNum (0 .. $#ColLabels) { 492 $ColLabel = $ColLabels[$ColNum]; 493 $TextFilesColLabelToNumMap[$Index]{$ColLabel} = $ColNum; 494 } 495 close TEXTFILE; 496 } 497 if ($TextFilesErrorCount) { 498 die "Error: Problems with input text file(s)...\n"; 499 } 500 } 501 502 # Setup script usage and retrieve command line arguments specified using various options... 503 sub SetupScriptUsage { 504 505 # Retrieve all the options... 506 %Options = (); 507 $Options{mode} = "colnum"; 508 $Options{indelim} = "comma"; 509 $Options{outdelim} = "comma"; 510 $Options{quote} = "yes"; 511 $Options{startcolmode} = "after"; 512 if (!GetOptions(\%Options, "help|h", "indelim=s", "columns|c=s", "keys|k=s", "mode|m=s", "outdelim=s", "overwrite|o", "quote|q=s", "root|r=s", "startcol|s=s", "startcolmode=s", "workingdir|w=s")) { 513 die "\nTo get a list of valid options and their values, use \"$ScriptName -h\" or\n\"perl -S $ScriptName -h\" command and try again...\n"; 514 } 515 if ($Options{workingdir}) { 516 if (! -d $Options{workingdir}) { 517 die "Error: The value specified, $Options{workingdir}, for option \"-w --workingdir\" is not a directory name.\n"; 518 } 519 chdir $Options{workingdir} or die "Error: Couldn't chdir $Options{workingdir}: $! \n"; 520 } 521 if ($Options{mode} !~ /(^(colnum|collabel)$)/i) { 522 die "Error: The value specified, $Options{mode}, for option \"-m --mode\" is not valid. Allowed values: colnum, or collabel\n"; 523 } 524 if ($Options{indelim} !~ /^(comma|semicolon)$/i) { 525 die "Error: The value specified, $Options{indelim}, for option \"--indelim\" is not valid. Allowed values: comma or semicolon\n"; 526 } 527 if ($Options{outdelim} !~ /^(comma|semicolon|tab)$/i) { 528 die "Error: The value specified, $Options{outdelim}, for option \"--outdelim\" is not valid. Allowed values: comma, tab, or semicolon\n"; 529 } 530 if ($Options{quote} !~ /^(yes|no)$/i) { 531 die "Error: The value specified, $Options{quote}, for option \"-q --quote\" is not valid. Allowed values: yes or no\n"; 532 } 533 if ($Options{startcolmode} !~ /(^(before|after)$)/i) { 534 die "Error: The value specified, $Options{quote}, for option \"--startcolmode\" is not valid. Allowed values: before or after\n"; 535 } 536 $OutDelim = ($Options{outdelim} =~ /^tab$/i ) ? "\t" : (($Options{outdelim} =~ /^semicolon$/i) ? "\;" : "\,"); 537 $OutQuote = ($Options{quote} =~ /^yes$/i) ? 1 : 0; 538 } 539