All notable changes to ADIF Multitool will be documented in this file. The format is based on Keep a Changelog.
ADIF Multitool is still in the “v0” phase, and some user-facing functionality
may change, though so far the interface has been stable. Users calling adifmt
from scripts are encouraged to use the GNU/POSIX two-dash --option
style
rather than the Go one-dash -option
style, since support for the latter could
be dropped. During v0 there is no commitment to API stability of the adif
,
adif/spec
, or cmd
Go packages. If you use this as a library in your own Go
program I would appreciate hearing about it so the API can be evolved with your
input.
count
command prints the number of records of each combination of a set of fields. For example,adifmt count --fields BAND,MODE
prints the number of contacts made for each band plus mode combination. If a field is blank or not set on a particular record it contributes an empty string to the combination.adifmt count
without the--fields
option prints the total number of records in the file. CSV or TSV output makescount
output easy to pass to another program like a spreadsheet for further analysis.CONT
(continent) works withadifmt infer
andadifmt validate
based on theDXCC
orCOUNTRY
field.validate --required-fields
supports conditionals (--if
,--if-not
,--or-if
,--or-if-not
) to determine which records must have certain fields set. All records are checked for data type validity, e.g. number formatting.validate
will produce an error if latitude is given as east/west or if longitude is given as north/south. It is also an error for latitude to be greater than 90°, not just greater than 180°.validate
will warn ifLAT
orLON
is set but the other one isn’t; likewise forMY_LAT
/MY_LON
. It’s possible to know latitude without also knowing longitude, but modern technology usually gives both together, so you probably had a copy-paste error.validate
handles theCNTY_ALT
/MY_CNTY_ALT
field, currently only used for New Zealand regions. Currently doesn’t require that each enumeration name only appears once.
infer
will set the relevant zone field if theDXCC
orCOUNTRY
field is set and the entity is in a single zone. It will also infer the zone if theSTATE
field is set and the state is only in one zone and the ADIF primary administrative division enumeration indicates the zone of the subdivision. For example,COUNTRY=India
will setCQZ=22 ITUZ=41
because India does not overlap CQ or ITU zone boundaries.COUNTRY=Kazakhstan
will setCQZ=17
but not setITUZ
at all, since Kazakhstan straddles the ITU Zone 29/30 boundary and ADIF does not define any subdivisions for the country.DXCC=291
(USA) would infer nothing because it’s in both multiple CQ Zones and multiple ITU Zones.DXCC=291 STATE=CA
would inferCQZ=3 ITUZ=6
since California is in just one zone of each type, butDXCC=291 STATE=MT
would just inferCQZ=4
since Montana is in two ITU Zones.validate
will consider a record valid if the CQ and ITU Zones (if present) are consistent with the DXCC and primary subdivision. No additional location checks, e.g. comparing gridsquare to zone boundaries, is done.MY_CQ_ZONE
andMY_ITU_ZONE
work as well.- CQ and ITU Zones also work for DXCC entities which have been removed from the active list, e.g. Zanzibar.
- Some multi-zone countries are missing zone data in the primary administrative subdivision enumeration. An ADIF proposal to expand and correct this data has been proposed, but it may be some time before the next ADIF version. ADIF Multitool may add its own subdivision associations before then.
- There is some variance between amateur radio organizations on exactly where ITU boundaries lie. This program uses the CQWW WAZ list for CQ-zone-to-entity associations, the AARL DXCC list for ITU-to-entity associations, and zone-check.eu to determine which ITU Zones a subdivision crosses. See also the mapability links above for some explanation of data challenges. Maritime boundaries between zones are not well defined and this program does not attempt to map geographic points to zones (or to geopolitical entities).
Started a changelog file so it’s easier to learn what’s new in a release.
- Consistently trim leading and trailing space from ADI and ADX comments. If a comment is nothing but space, don’t preserve it in the output. Note: record comments and file comments are preserved from input through output, but header comments, such as the text at the top of an ADI file, are ignored. This could change in the future, but I don’t want to preserve all the “Generated” lines created as part of a pipeline. See discussion.
- Franz Josef Land DXCC entity is part of Russia, Arkhangelsk Oblast.
Nothing yet
Upgrade data specification to ADIF 3.1.5.
Upgrade golang.org/x/crypto package.
--field-order
option to control the order of fields in the output. Any fields
not in the list will still be included in the output.
Add some practical command examples to the README.
- Cabrillo: flexible ADIF field mapping to Cabrillo exchange. The WWROF
Cabrillo documentation gives an example exchange format (RST and SRX/STX),
not the only valid exchange format. See README or
adifmt help cabrillo
for examples of--cabrillo-their-exchange
and--cabrillo-my-exchange
options. - CSV and TSV:
--csv-omit-header
and--tsv-omit-header
to only print records, no header row. This makes it easy to process the output with other POSIX utilities likesort | uniq
without needing to pipe throughtail +2
first. - Filenames can now come before or after
--
options, e.g.adifmt command file1.adi --option1=foo --option2=bar file2.adi
. Previously filenames needed to be after all--
options, which made it challenging to replace a filename from the end of the first step of a long pipeline.
- Fix crash in
sort
when sorting fields with a list of strings. - Cabrillo: treat multiple phone modes (e.g. SSB, AM, and FM) as SSB and treat RTTY plus other digital modes as DIGI, rather than MIXED.
- Cabrillo: support tab field delimiter, don’t leave dangling spaces, and other minor fixes.
- ADX: output a newline at the end of the file.
- Fix user-defined field format in
help
output.
validate
: warn if a date or time is in the future.
Support whitespace delimiters in flatten
, e.g.
adifmt flatten --fields SRX_STRING --delimiter 'SRX_STRING= '
to turn a QSO
party county-line record with exchange ABC DEF
into two QSOs. Delimiters may
also be quoted, e.g. --delimiter 'foo="\t"'
.
Internal improvements to make command-line options easier to test.
adifmt infer --fields USACA_COUNTIES,MY_USACA_COUNTIES
from the CNTY
and
MY_CNTY
in the US. Also infers CNTY
from USACA if there’s only one in the
list.
flatten
command to convert multi-value fields into multiple records. This is particularly useful along withadifmt infer
for turning multi-park contacts (POTA_REF=US-4572,US-4576
) into multiple QSOs (SIG=POTA SIG_INFO=US-4572
andSIG=POTA SIG_INFO=US-4576
), as expected by POTA uploads.- Cabrillo:
--their-exchange-field-alt
option so contest exchange can come from two fields. This is useful for example in a QSO party whereSRX_STRING
was only filled out for in-state county contacts and out-of-state values were recorded in theSTATE
field.
- Make
help
output less overhelming; only show format-specific options when asked explicitly likeadifmt help csv
. - Associate more DXCC entities with their parent ISO 3166-1 codes.
adifmt fix
can now, in most cases, pick the right DXCC entity ifSTATE
is set to a known primary subdivision code andCOUNTRY
is set to an ISO code, e.g.COUNTRY=USA STATE=AK
setsCOUNTRY=ALASKA DXCC=6
. - Improve validation of primary subdivision validation. If ADIF does not define
subdivisions for a country,
validate
logs a warning if there’s a value in theSTATE
field. If the country has subdivisions defined and theSTATE
doesn’t match, it reports an error. - Release process improvements.
- Cabrillo: preserve frequency precision when converting between MHz and kHz.
Upgrade golang.org/x/crypto package.
Release process improvements. adifmt version
shows git revision.
adifmt validate --required-fields
option to ensure an expected set of fields are set on each record.adifmt edit --rename old=new
to change a field’s name. Doesn’t permit overwriting existing data, but cyclical names like--rename name=my_name --rename my_name=name
are supported.
Fix build error on Go 1.18.
Automated GitHub releases. Thanks @pcunning!
Support for Cabrillo 3.0 contest log format.
Converts Cabrillo to and from ADIF. Cabrillo header fields can be set with
command-line options or APP_CABRILLO_
app-specific fields in the ADIF header.
Headers converted from Cabrillo are preserved in ADIF. Some header fields are
inferred if all QSOs are equal or fit a category. Make sure to check the values
in a text editor before submitting your log, though.
Fix build error on Go versions before 1.20.
Conditions, comparisons, and the find
and sort
commands. find
filters a
log to only records matching a condition. sort
orders a log by the specified
--fields
list.
Commands which take conditionals accept --if
, --if-not
, --or-if
,
--or-if-not
options to define a boolean condition. The --or
options split
groups of AND conditions. Conditions support string and numeric equality, and
less-than, greater-than, and less-equal/greater-equal comparisons. Equality can
check several values at once like --if 'band=40m|20m'
. “Not equals” is
expressed as --if-not mode=CW
. Fields can be compared with other fields using
braces, e.g. --if 'TIME_ON<={TIME_OFF}'
.
- Use
adif edit --if field=value
to only apply edits to records matching a particular condition. - Use
{FIELD}
as a template in a filename, e.g.adifmt save '{STATION_CALLSIGN}_{QSO_DATE}'
.
Use 1-based record indexing in error and warning messages.
Allow “ragged” CSV files with different field counts in each line.
Improved error handling.
Ignore case in scoped enum validation.
Properly validate scoped enumerations. The STATE
field needs to be a primary
administrative subdivision of the COUNTRY
in the record, not just a valid
abbreviation in any country.
Map ISO 3166-1 alpha codes to DXCC
entity names in adifmt fix
. This allows you to write USA
and ZA
in the
COUNTRY
field and transform them to UNITED STATES OF AMERICA
and REPUBLIC OF SOUTH AFRICA
which adifmt infer
can use for the DXCC number.
Adhere to ADIF spec with CRLF line breaks and limit to ASCII if --adi-ascii-only
option is set. (Default behavior allows UTF-8 data.)
First numbered version. Supports cat
, edit
, fix
, infer
, select
,
save
, help
, and version
commands. Supports ADI
, ADX
, CSV
, TSV
,
and JSON
formats.