234

I have a file that contain list of files I want to archive with tar. Let's call it mylist.txt

It contains:

file1.txt
file2.txt
...
file10.txt

Is there a way I can issue TAR command that takes mylist.txt as input? Something like

tar -cvf allfiles.tar -[someoption?] mylist.txt

So that it is similar as if I issue this command:

tar -cvf allfiles.tar file1.txt file2.txt file10.txt 
neversaint
  • 60,904
  • 137
  • 310
  • 477
  • 4
    The tar man page is extremely unhelpful for this option (at least on RedHat 5.4 thru 6.3): "-T: get names to extract or create from file F". "Extract or create" sounds like it applies to taking files out of the tar archive, but not putting them in. The `-X` exclude option survives from the old Unix tar command, but apparently -I (include) did not! – Ogre Psalm33 Dec 18 '13 at 14:49
  • There are few `man` pages with an `EXAMPLES` section, despite it being a [standard section](https://linux.die.net/man/7/man-pages). See . – sam boosalis Apr 29 '19 at 10:22

6 Answers6

355

Yes:

tar -cvf allfiles.tar -T mylist.txt
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 1
    I wish I could put comments in mylist.txt .. is there any workaround using some tar option from inside mylist.txt ? – Stphane Aug 10 '18 at 10:50
  • 12
    @Stphane that's simple, using the --exclude flag allows this. Assuming your comment lines start with a '#', a command such as the following would ignore / exclude any attempted file operations on lines containing cmments, i.e. your command can look like this: tar -cvf allfiles.tar --exclude='^#' -T mylist.txt. Tar reports an error, but when you check your tar archive, there are no errors, and all files from the list are inside your archive. – Matt G Oct 31 '18 at 06:05
  • Pointing out that this command is for linux variant and for those on sunOS or other variants, do check out the other answers below. E.g. For sunOS, two alternatives I have tested: tar -cvf file.tar -I list.txt and tar -cvf file.tar $(cat list.txt) – Nasri Najib Sep 02 '19 at 08:37
  • 1
    `-L mylist.txt` on AIX – Roland Apr 24 '20 at 11:32
  • You may also want to add a "--verbatim-files-from" option (before the -T), otherwise items in the list file which start with a dash (like -h or --dereference) will be treated as tar commands. – William Sep 27 '21 at 18:52
93

Assuming GNU tar (as this is Linux), the -T or --files-from option is what you want.

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
58

You can also pipe in the file names which might be useful:

find /path/to/files -name \*.txt | tar -cvf allfiles.tar -T -
woot
  • 7,406
  • 2
  • 36
  • 55
  • 2
    What if the .txt files list is really huge ? Should one use xarg command with tar -r.. instead of tar -c.. ? – Stphane Dec 15 '15 at 22:42
  • 3
    @Stphane Hmm, I don't think the length of the list matters much for this method. In fact, I would imagine this method is better than xargs as xargs will rerun tar over and over to append data, but I haven't really tested the methods side by side. – woot Mar 01 '16 at 20:28
  • 6
    When a pipe is employed, which is the case here, the operating system creates streams on both sides of the pipe and synchronizes production and consumption of data. The list of files could be infinite. You could tar/gz the entire internet using a Raspberry Pi Zero, given that you have enough storage on the end of the pipe. – Richard Gomes Dec 29 '19 at 13:06
  • @Stpihane if you did eg `find /path/to -name '*.txt' -exec tar -cvf all.tar {} \+` you'd be in trouble, yes, as `find` would execute the tar command multiple times with successive subsets of the files. Only the last subset would be in the archive, as it would be created anew for each tar execution. – drevicko Aug 30 '20 at 13:33
  • My one-liner to use with pigz: `find /path/to/files -name '*.log*' | tar -cvf - -T - | pigz -9 > logs.tgz` – Stalinko Dec 23 '20 at 10:21
21

Some versions of tar, for example, the default versions on HP-UX (I tested 11.11 and 11.31), do not include a command line option to specify a file list, so a decent work-around is to do this:

tar cvf allfiles.tar $(cat mylist.txt)
barush
  • 303
  • 2
  • 6
  • 6
    *UUoC* (unnecessary use of `cat`), simply `$( – David C. Rankin Jul 25 '16 at 06:21
  • 5
    note that this may exceed the maximum length of the command line if `mylist.txt` is large – Andre Holzner Dec 04 '17 at 06:35
  • in that case `tar -T <( – Mike D May 31 '18 at 18:27
  • Just wonder if this would work 'cat mylist.txt | tr '\n' '\0' | xargs -0L1 tar rf allfiles.tar' to avoid exceeding command line length. With 'tar rf' files are appended to archive. -0L1 stands for taking only one line from the file. -0L2, -0L3, ... should also be possible – grenix Oct 27 '21 at 17:12
10

On Solaris, you can use the option -I to read the filenames that you would normally state on the command line from a file. In contrast to the command line, this can create tar archives with hundreds of thousands of files (just did that).

So the example would read

tar -cvf allfiles.tar -I mylist.txt
Jan
  • 341
  • 5
  • 15
7

For me on AIX, it worked as follows:

tar -L List.txt -cvf BKP.tar
jww
  • 97,681
  • 90
  • 411
  • 885