2

I have a tgz file with the following file structure

- folder
    - subdir1
      - file1.txt
      - file2.text
    - subdir2
      - file1.txt

When i run tar -tf folder.tgz, it outputs the following:

folder/
folder/subdir1/
folder/subdir1/file1.txt
folder/subdir1/file2.txt
folder/subdir2/
folder/subdir2/file1.txt

How can i exclude directory names so that the outputted list is:

folder/subdir1/file1.txt
folder/subdir1/file2.txt
folder/subdir2/file1.txt
alpha787
  • 29
  • 1
  • 7
    tar -tf folder.tgz | grep -v /$ – Bib Nov 07 '21 at 17:30
  • 5
    @Bib pelase don't post answers in comments. That circumvents the site's quality control procedure since comments cannot be downvoted and also can discourage others from answering which results in the question left unanswered. Also note that your approach would fail if any of the paths contain newline characters. – terdon Nov 07 '21 at 18:19
  • 1
    @terdon, I've just checked, and yes it does catch new lines in file & directory names, since they are stored as, for example, -rw-r--r-- b/users 0 2021-11-07 19:00 rr/hh\nll, and that is how they are displayed. Thank you for asking... – Bib Nov 07 '21 at 19:03
  • 3
    @bib see, this is why we need answers: you are quite right that GNU tar seems to do this (nice!) but that isn't the case for other tar flavors (I just tested with busybox tar for example) and an answer could explain this and show the limitations. – terdon Nov 07 '21 at 19:05
  • 3
    I could always roll my own tar and have it convert new lines into pictures of chickens. – Bib Nov 07 '21 at 19:06
  • 1
    @Bib here is an implementation: perl -MArchive::Tar -le 'for(Archive::Tar->new(shift)->get_files){print $_->name=~s/\n//gr if $_->type!=5}' archive.tgz –  Nov 08 '21 at 14:55

3 Answers3

5

Use awk. Very well explained in this answer: tar list files only

tar tzf your_archive | awk -F/ '$NF !=""'

Note that this assumes your tar implementation prints a literal \n if the paths contain newlines. GNU tar and bsdtar do this, but busybox tar and, presumably, others do not.

αғsнιη
  • 41,407
LincolnP
  • 526
  • 1
    Note that this will fail if any of the paths contain newlines. – terdon Nov 07 '21 at 18:20
  • 1
    Have you actually tested that terdon, or are you just making an assumption? – Bib Nov 07 '21 at 19:05
  • 1
    @Bib both, actually. I was assuming (which is why I hadn't voted). But your comment made me test and see that GNU tar does indeed print literal \n but others don't which is why I just edited this answer again. – terdon Nov 07 '21 at 19:07
  • or even ... |awk '/[^/]$/' – αғsнιη Nov 08 '21 at 16:53
5

With star (from schily-tools):

star tzf file.tgz -find ! -type d
4

If using GNU tar and your tar file isn't huge, you can use the --to-command option to run a command on each file:

% tar c folder | tar x --to-command 'printf "%s\n" "$TAR_REALNAME"'            
folder/subdir1/file1.txt
folder/subdir1/file2.txt
folder/subdir2/file1.txt

Currently the option only sends regular files to the command, but it's not hard to guard against directories being supported in the future, by using the TAR_FILETYPE variable set by tar:

% tar c folder | tar x --to-command '[ "$TAR_FILETYPE" != d ] && printf "%s\n" "$TAR_REALNAME"'
folder/subdir1/file1.txt
folder/subdir1/file2.txt
folder/subdir2/file1.txt
muru
  • 72,889