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

Script to convert an Amateur Radio Cabrillo format log file into to an ADIF(Amateur Data Interchange Format) logfile.

A Cabrillo file has space delimited fields. An ADIF file has tag delimited fields and field order is not important. A Cabrillo file is used for entry into Ham radio contests like the ARRL Field Day. ADIF files are used to import contact data into logging software like QRZ.com. This process was used to create(with QRZlogfmt.pl) a Cabrillo log of 200+ entries and then import this file into my log on QRZ.com. I prefer to log on paper and I will use this process to enter and import contact data as I fill a log sheet.

Posted here so it can be found by the search engines. Other utilities that I have found are for Windows only.

#! /usr/bin/perl # adif.pl - Convert a Cabrillo format Ham Radio # log file into an ADIF format # # James M. Lynes Jr. - KE4MIQ # Created: July 16, 2021 # Last Modified: 07/17/21 - Initial header info # 07/20/21 - Change input filename # 07/20/21 - Add the file output # 07/21/21 - Changed output file extension to .adi # to make QRZ.com file-import happy # Notes: Handles two types of exchanges: # 1. Contest exchange, 11 fields - Class, Section # QSO:,7225,PH,2021-01-30,1943,KE4MIQ,1H,WCF,K5LDA,1H,A +L # # 2. Usual exchange, 9 fields - RST, RST # QSO:,7225,PH,2021-01-30,1943,KE4MIQ,59,K5LDA,59 # # Commas inserted manually into the Cabrillo file log.t +xt # Search/Replace all spaces with commas # Search/Replace ,,, with , # Search/Replace ,, with , # # Cabrillo file created with another Perl script(QRZlog +fmt.pl) # Unfortunately fields are defined by position # order within the record # # ADIF(Amateur Data Interchange Format) format # is a field order independant, tagged format # use strict; use warnings; open(my $infile, "<", 'log.txt') or die "Can't open log.txt: $!"; open(my $outfile, ">", 'adif.adi') or die "Can't open adif.adi: $!"; my @fields; my $fields; my $numfields; while(defined(my $line = <$infile>)) { chomp($line); @fields = split /,/, $line; $numfields = scalar @fields; print "Number of Fields: $numfields\n"; if($numfields == 11) { # Type 1, C +ontest $fields[1] = sprintf "%6.3f", $fields[1]/1000.; #KHz -> MHz $fields[1] =~ s/^\s+//; # Remove le +ading spaces $fields[2] =~ s/PH/SSB/; # Change PH + -> SSB $fields[3] =~ s/-//g; # Remove - +twice my $l1 = length($fields[1]); # Field len +gths my $l67 = length("$fields[6] $fields[7]"); my $l8 = length($fields[8]); my $l910 = length("$fields[9] $fields[10]"); print $outfile "<freq:$l1>$fields[1] "; # +Freq print $outfile "<mode:3>$fields[2] "; # +Mode print $outfile "<qso_date:8>$fields[3] "; # +Date print $outfile "<time_on:4>$fields[4] "; # +Time print $outfile "<rst_sent:$l67>$fields[6] $fields[7] "; # +Sent exch print $outfile "<call:$l8>$fields[8] "; # +Call print $outfile "<rst_rcvd:$l910>$fields[9] $fields[10]"; # +Recv exch print $outfile " <eor>\n"; # +End of Record } elsif($numfields == 9) { # Type 2, U +sual $fields[1] = sprintf "%6.3f", $fields[1]/1000.; #KHz -> MHz $fields[1] =~ s/^\s+//; # Remove le +ading spaces $fields[2] =~ s/PH/SSB/; # Change PH + -> SSB $fields[3] =~ s/-//g; # Remove - +twice my $l1 = length($fields[1]); # Field len +gths my $l6 = length($fields[6]); my $l7 = length($fields[7]); my $l8 = length($fields[8]); print $outfile "<freq:$l1>$fields[1] "; # +Freq print $outfile "<mode:3>$fields[2] "; # +Mode print $outfile "<qso_date:8>$fields[3] "; # +Date print $outfile "<time_on:4>$fields[4] "; # +Time print $outfile "<rst_sent:$l6>$fields[6] "; # +Sent exch print $outfile "<call:$l7>$fields[7] "; # +Call print $outfile "<rst_rcvd:$l8>$fields[8]"; # +Recv exch print $outfile " <eor>\n"; # +End of Record } }

James

There's never enough time to do it right, but always enough time to do it over...