Question: I'm using Windows 10 (which complicates things).

So I have a bunch of music files and associated cover picture in the form of "x.m4a" and "x.jpg". I would like to associate them.

A command-line tool would be ideal since it could be easily run in a batch. Basically, I would like to use this:

```
@for /R %%F in (*.m4a) do (
    <utility> "%%~F" +cover "%%~npF.jpg"
)

```

Neither Foobar2000 nor Mp3tag provide a CLI, so I tried with ffmpeg directly but it automatically converts the picture in png which I don't want.

I tried using id3 mass tagger with

```
id3 -2 -wAPIC "test.jpg" "test.mp3"

```

But it returned with "writing `APIC' frames is not supported".

Answer: 
**Short answer: yes, it is safe to use Python `tarlib` to compress the data, nothing is lost compared to BSD `tar`.**

Underlying issue: sorting
-------------------------

I think the underlying issue is that BSD `tar` and GNU `tar` without any sort options put the files in the archive in an undefined order.

GNU `tar` has a `--sort` option:

> 
> sort directory entries according to `ORDER`, which is one of `none`, `name`, or `inode`.  
> 
> The default is `--sort=none`, which stores archive members in the same order as returned by the operating system.
> 
> 
> 

### Testing GNU `tar`

To test this I installed GNU `tar` on my Mac with:

```bsh
brew install gnu-tar

```

And then tarred the same folder, but with the `--sort` option:

```bsh
gtar --sort='name' -cJf zsh-archive-sorted.tar.xz /Users/user/Desktop/temp/tar/2021-03-11

```

The `zsh-archive-sorted.tar.xz` archive is 1.5 MB, equal to the size of the archive created by the Python library.

### Concatenating in sorted order

The effect sorting has on the final archive size is further demonstrated by first concatenating all the JSON files sorted by name (which has the creation unixtime at the beginning of it) and then tarring with BSD `tar`:

```bsh
cat *.json > all.txt
tar cJf zsh-cat-archive.tar.xz all.txt

```

The `zsh-cat-archive.tar.xz` archive is also 1.5 MB.

### Python `tarfile` sorting

Finally, the [documentation of the Python `TarFile.add` function](https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.add) confirms that Python `tarfile` sorts by default:

> 
> Directories are added recursively by default. This can be avoided by setting recursive to False. Recursion adds entries in sorted order.
> 
> 
> 

Why sorting matters
-------------------

I think the reason sorting has such an impact in my case is as follows:

My JSON files contain locations of hundreds of vehicles. Every minute I read out all the locations, but only a few of these locations have a different value from minute to minute.  

By sorting the files by name, two subsequent files have little different characters between them.
Apparently this is very favourable for the compression efficiency.
Try setting the compression levels in the macOS command line.
-------------------------------------------------------------

I know you are asking about [`xz`](https://linux.die.net/man/1/xz) but explained in [this answer here](https://superuser.com/a/305141/167207), on older versions of GZip you can set the compression level with an environment variable like this:

```
GZIP=-9 tar cf zsh-archive.tar.xz folderpath

```

That said, that only seems to work with GZip 1.8 and is depreciated on later versions. So use the `-I`/`--use-compress-program=COMMAND` option for tar instead; note this option might not work on macOS but placing here anyway just in case. So the command would then change to:

```
tar -I 'gzip -9' -cf zsh-archive.tar.xz folderpath

```

And yes, these examples would be compressing the archive Gzip instead of `xz`, but you can easily change the command to this to use `xz` like this:

```
tar -I 'xz -9' -cf zsh-archive.tar.xz folderpath

```

The `xz` compression level ranges from `-0` to `-9` with the default being `-6`; so `-9` is the highest compression level.

Just note that `xz` is not installed on macOS by default. To install it on macOS you must first install [Homebrew](https://brew.sh) and then install [`xz`](https://formulae.brew.sh/formula/xz) via Homebrew like this:

```
brew install xz

```