For various reasons I decided to use RAR archive to store some data, instead compressed tar.

Happy with decision, except for one thing: I can't find a way to store files sorted. Order of files is important as I plan to query archive and results should be ordered.
My file structure is like this:


so folders represent years and files inside are numbered. Using ls, tar or any program lists files as expected. If I try to create non-recursive rar archive (i.e. compress files only in folder 2000), files are stored sorted, but if I try to add files recursively (rar a -r) then files are messed up.

I can't find any switch except:

n@            Read file names to include from stdin

with which I had no luck to make it usable.

I could call rar on every file like:

for f in */*.txt ; do rar a -r archive.rar $f ; done

but that's not very smart.

Any ideas?

As I commented below answer, I though to update question:

I managed to store sorted files similarly as in above not so clever line:

for d in */ ; do rar a -r archive.rar $d*.txt ; done

which works fine for above particular scenario, of course

I haven't found how to use n@ switch yet thou. I use RAR 4.10 beta 5


Using rar on Ubuntu

(RAR 3.90 beta 2 Copyright (c) 1993-2009 Alexander Roshal 3 Jun 2009)

the best that you can do is this:

find * -type f | sort | xargs rar a ../eliezer.rar

Which you unpack with:

unrar x eliezer.rar

At least this does not call rar for every file.

The -n@ switch seems to work only for files. For example:

find * -type f | rar a ../eliezer.rar -n@

produces "WARNING: No files" if there are no regular files in the CWD, but

find * -type d | rar a ../eliezer.rar -n@ -r

works for the directories.

The rar recursive switch -r reads the file names in the order that they appear in the dirent struct (man readdir). So the only way that you could change the order that rar packs the files would be to manipulate the order of the files in the directory file structures (usually the creation order) before calling rar. You could do this with a directory editor, with the caveat that some file system types might change the order of the files in the directory structure as part of their garbage collection or optimization.

  • find . is more idiomatic than find *. If you need to get rid of the "./" component, find -printf "%P\n" works. If your tools can handle NULs, I would actually recommend find . -type f -printf "%P\0" | sort -z | xargs -0 rar a ../foo.rar, as it properly handles filenames with newlines. Actually, I'd recommend find dir -type f -print0 | sort -z | xargs -0 rar a dir.rar, as it's considered polite in unix-circles to unpack archives into subdirectories. The -type f is needed: the containing directory gets sorted before its files, and rar will pack them using the directory order. – wnoise Mar 31 '12 at 22:03
  • Thanks Eli for your answer, but unfortunately none of provided examples stores file sorted here. I'm also on Ubuntu. find * | sort lists files sorted but find * | sort | xargs rar ... stores files in unsorted order for some reason. I tried also -n@ (with additional sort command) which works fine as in your snippets, but again it does not store sorted files. I could provide screenshot from terminal if anyone requests it. So for me, snippet that works is the last update to my question: for d in */ ; do rar a -r archive.rar $d*.txt ; done which loops over folders and is acceptable to me – zetah Apr 1 '12 at 10:17
  • Either mistake in my original post or an editing error. I re-edited now. Should read find * -type f | sort | xargs rar a ../eliezer.rar – Eli Rosencruft Apr 1 '12 at 14:14

Do you really care how rar "stores" the data?
Wouldn't unrar v archive.rar |sort give you a properly sorted list?

  • Yes, I do, as I pipe uncompressed output to stdout with rar p. BTW unrar -v switch you mention, does not do anything here - did you test it? – zetah Mar 31 '12 at 11:49
  • of course I tested my complete answer, creating dirs and files matching the pattern you mentioned. the switch is v not -v (my typo) I think that depending on how rar stores its data is likely to become problematic sooner or later. I would suggest tar over rar if you truly care about the internal data structure. Maybe use more than one tar file to reduce the overhead of updates. – bsd Mar 31 '12 at 17:05
  • Yeah, I started with gzipped tar and then wanted to update archive... rest is history, w/o even mentioning all handy rar options – zetah Mar 31 '12 at 19:50

I had a similar problem as stated in the Question and came up with this soluition:

for d in *; do find "${d}/" -type f | sort | rar a "${d}.rar" @; done
  1. it lists all directories (only dirs in that folder!)
  2. list all the files in one of the dirs
  3. sort
  4. use the @ without anything sin

Information on this seems very sparse. However this question still helped me work out how to do it. So I'll post the process here for future searchers.

According to: http://acritum.com/winrar/console-rar-manual

RAR command line syntax:
RAR <command>  [ -<switches> ]  <archive>  [ <@listfiles…> ]
[ <files…> ]  [ <path_to_extract\> ]

Listfiles are plain text files that contain names of files to process.
File names should start at the first column. It is possible to
put comments to the listfile after // characters. For example,
you may create backup.lst containing the following strings:

c:\work\doc\*.txt         //backup text documents
c:\work\image\*.bmp       //backup pictures

and then run:

rar a backup @backup.lst

If you wish to read file names from stdin (standard input),
specify the empty listfile name (just @).

Win32 console RAR uses OEM (DOS) encoding in list files.

You may specify both usual file names and list files in the same
command line. If neither files nor listfiles are specified,
then *.* is implied and RAR will process all files

So the process would be:

  1. Change to the root of the location you wish to archive from or use absolute paths. But be aware that an absolute path will end up in the archive too.
  2. And then create the listfile

    find topFolderOfTarget -type f | sort > listFile.txt

  3. Then run rar with @listfile.txt

    rar a archiveName @listFile.txt

Alternatively you can skip making a list file:

find topFolderOfTarget -type f | sort | rar a archiveName @

The reason this was useful to me is that I was creating a multipart archive and uploading it for a backup. If I only want a file or folder or 2 then I can simply get the relevant parts and avoid downloading the whole thing. Confident that the contents will be properly grouped.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.