# TAR list of files and folders date and time more convenient view?



## maks (Oct 25, 2018)

Hi everyone

TAR of the FreeBSD by default do output of the archives's files list like this:

```
user@freebsd:~/archives % tar -tvf ./test.tar.gz
-rw-r--r--  0 group user 28405 Jun 29  23:33 ./abc/123/file.dat
-rw-r--r--  0 group user 48118 Dec  4  2015 ./abc/123/mysql.dat
-rw-r--r--  0 group user 19068 Mar  8  2018 ./abc/123/backup.txt
```

Question. How to get output of date and time like this ?

```
user@somelinux:/mnt/abc/ $ tar -tvf ./_files.tar.gz
-rw-r--r-- group/user 5072 2018-10-24 10:55 ./files/file.php
-rw-r--r-- group/user 4161 2018-10-16 15:06 ./files/abc.php
-rw-r--r-- group/user 6810 2018-07-30 13:28 ./files/gbc.txt
```

Is this possible to get date and time in more _convenient_ format ?

I have read all this manual https://www.freebsd.org/cgi/man.cgi?tar(1) and have not found anything.

Thank you in advance.


----------



## maks (Oct 25, 2018)

Either at least like `ls` output format

```
user@freebsd:~/archives % ls -lT
-rw-r--r--  1 group  user   75002 Oct 22 13:54:44 2018 files.7z
drwxr-xr-x  5 group  user     512 Oct 25 11:09:47 2018 engine
-rw-r--r--  1 group  user    1630 Oct 24 11:20:35 2018 index.php
-rw-r--r--  1 group  user  873232 Jul  2 12:42:00 2018 test.tar.gz
user@freebsd:~/archives %
```


----------



## maks (Oct 26, 2018)

I'm have solved this own. Been downloaded a GNU tar source code, then compiled to custom path and it works well now.


```
[user@freebsd64 ~/_tar]$ ./tar tvf ./tar-latest.tar.gz
drwxr-xr-x gray/gray         0 2017-12-17 03:29 tar-1.30/
-rw-r--r-- gray/gray      2299 2017-01-02 04:43 tar-1.30/acinclude.m4
-rw-r--r-- gray/gray    206632 2017-01-02 04:44 tar-1.30/ChangeLog.1
-rw-r--r-- gray/gray     91929 2017-12-17 03:25 tar-1.30/config.h.in
-rw-r--r-- gray/gray      2822 2015-08-24 00:38 tar-1.30/Make.rules
drwxr-xr-x gray/gray         0 2017-12-17 03:29 tar-1.30/doc/
```

Much better.


----------



## Beastie (Oct 26, 2018)

maks said:


> Downloaded GNU tar, then compiled to custom path and it works well now.


GNU tar is available in the ports tree (archivers/gtar) and as a binary package.


----------



## ralphbsz (Oct 26, 2018)

This seems to be a "XY problem": You are asking us about the details of your proposed solution, but we don't know why you are asking.  What are you really trying to accomplish?  Why does the exact format of the date matter to you?

My educated guess: You are taking the output from "tar tv...", and parsing it with some other program or script.  Perhaps you can not change that program or script, which forces you to make the data that goes into it be in the right format.  Perhaps simply using gnu tar is the easiest solution for that approach.  But there are many others.  For example, it would be easy to download the source code for BSD tar (since downloading the source to any part of the system is easy), and modifying it quickly in place to print in a different format.  A different solution might be to write a tiny script that takes the output from the standards BSD tar, parses the date format, and outputs it in a different form.  You can for example use python's (or perl's?) function strptime to do the parsing, and then strftime to do the output.  For a knowledgeable python/perl/ruby/... developer, that's 10 minutes of work and probably 5 lines of code.

Perhaps another solution (which is probably better in the long run) would be to teach the program that consumes this information how to parse different date formats: strptime(3) might be your friend (the man page points to the C standard library version; I would recommend using it from an interpreted language rather than C though).

But in the end, here is yet another suggestion: Most likely, the program that looks at the output of "tar tv..." does so to select which things to extra from the tar file.  Perhaps you shouldn't be using a canned version of tar at all.  In python, reading tar files is super easy as a tar file reader is part of the standard library (I presume other scripting languages have similar functionality).  This might be the cleanest and most efficient thing to do.


----------



## leebrown66 (Oct 28, 2018)

And just for fun, if you want to avoid GNU, or ports:


```
$ tar tvf /tmp/x.tar
drwxr-xr-x  0 0      0           0 Aug 11 10:37 etc/nagios/Nyingma/
-r--r-----  0 nagios nagios      0 Dec 31  1969 etc/nagios/Nyingma/contacts.cfg
-r--r-----  0 nagios nagios    110 Aug 11 10:37 etc/nagios/Nyingma/command.cfg
-r--r-----  0 nagios nagios   2308 Aug 11 10:37 etc/nagios/Nyingma/switch-net.cfg
-r--r-----  0 nagios nagios    807 Aug 11 10:37 etc/nagios/Nyingma/switch-voip.cfg
drwxr-xr-x  0 0      0           0 Aug 11 10:37 usr/lib64/nagios/plugins/
-rwxrwx---  0 nagios nagios   1646 Aug 11 10:37 usr/lib64/nagios/plugins/check_port
```


```
$ cat /tmp/x.tar | tar -cf - --format=mtree @- | awk '{for(f=1;f<=NF;f++){if(substr($f,1,5)=="time="){cmd="date -j -r "substr($f,6,length($f)-7);cmd|getline t;close(cmd);break;}}print t,$1}'  #mtree
Sat Aug 11 10:37:57 PDT 2018 ./etc/nagios/Nyingma
Sat Aug 11 10:37:57 PDT 2018 ./etc/nagios/Nyingma/command.cfg
Wed Dec 31 16:00:00 PST 1969 ./etc/nagios/Nyingma/contacts.cfg
Sat Aug 11 10:37:57 PDT 2018 ./etc/nagios/Nyingma/switch-net.cfg
Sat Aug 11 10:37:57 PDT 2018 ./etc/nagios/Nyingma/switch-voip.cfg
Sat Aug 11 10:37:57 PDT 2018 ./usr/lib64/nagios/plugins
Sat Aug 11 10:37:57 PDT 2018 ./usr/lib64/nagios/plugins/check_port
```


----------



## maks (Oct 29, 2018)

ralphbsz said:


> This seems to be a "XY problem": You are asking us about the details of your proposed solution, but we don't know why you are asking.  What are you really trying to accomplish?  Why does the exact format of the date matter to you?


It just for more convenient output. Nothing else. The only things annoying me - the date and time format. I don't want to keep in mind all these conditions like when it shows the time instead year that means the file was recently changed or saved. When recently ? Today, month ago, last year? For every each machine it could be different. And this is confusing me. https://unix.stackexchange.com/ques...-time-for-some-files-but-only-year-for-others


> By default, file timestamps are listed in abbreviated form, using a date like ‘Mar 30 2002’ for non-recent timestamps, and a date-without-year and time like ‘Mar 30 23:45’ for recent timestamps. This format can change depending on the current locale as detailed below.


I could take BSD tar source code, spend about 1-2 hour(s) to find the part of the code and change it. But I don't have time for this. I have a task and need to solve this problem fast and easy as possible. Today when we have a google and can find out the problem and solve it within minutes no point to delve the source code. Wget, configure and then make install. This is it. Problem solved. Time is money.

```
user@freebsd:~/archives % tar -tvf ./test.tar.gz
-rw-r--r--  0 group user 28405 Jun 29  23:33 ./abc/123/file.dat
-rw-r--r--  0 group user 48118 Dec  4  2015 ./abc/123/mysql.dat
-rw-r--r--  0 group user 19068 Mar  8  2018 ./abc/123/backup.txt
```
This is completely inconvenient and useless format for me. This is really pretty simple thing, just give the readable and easy for understanding format. Why this simple thing is so complicated?

You mentioned `strptime`. How you would use it to convert BSD tar output date/time format to that I asked for ? Can you give examples please? Thank you in advance.


----------



## maks (Oct 29, 2018)

leebrown66 said:


> ```
> $ cat /tmp/x.tar | tar -cf - --format=mtree @- | awk '{for(f=1;f<=NF;f++){if(substr($f,1,5)=="time="){cmd="date -j -r "substr($f,6,length($f)-7);cmd|getline t;close(cmd);break;}}print t,$1}'  #mtree
> ```


Yes. It works for me as well. Thank you for good solution. I tried to play with AWK but not too much familiar with this software. You are a magician!


----------



## maks (Oct 29, 2018)

```
cat /tmp/x.tar | tar -cf - --format=mtree @-
```

Unfortunately doesn't work fast with large archives. Very-very slow.


----------



## ralphbsz (Oct 31, 2018)

I see.  You just want tar to give you consistent date format, for your particular taste in human reading it.  Makes sense now.

My proposed solution with "strptime" was to use the existing output from tar, and then use strptime to reformat it into being consistent.  The problem with this is that the default tar output doesn't have terribly much information: You can't rely on the hour/minute being present., because sometimes they get replaced by the year.  So here is something that would work, but would not always have the hour/minute (I'm using awk instead of pythons/C's strptime):

```
tar tvf ... | \
awk 'NF>8 {if (index($8, ":")>0) {printf "2018 %3s %2d %-5s\n", $6, $7, $8} else { printf "%4d %3s %2d ??:??\n", $8, $6, $7}}'
```
That gives you output roughly like this (I'm omitting the fields before and after the date, you'd have to add those back to the awk):

```
2018 May 27 11:05
2017 Nov 17 ??:??
2017 Nov  7 ??:??
2017 Nov  7 ??:??
2018 May 16 11:40
2018 Oct 11 19:13
2018 Jul 21 08:56
2013 Aug  2 ??:??
2018 Oct 27 17:52
```
If you look what I did here: I look at the three columns (6 through 8) which contain the date.  If the last column contains a ":", it is a hour/minute, and I assume the year is 2018, and print it at the end.  Otherwise, there is no hour minute and the last column is the year.

If you consistently want *both* year and hour/minute, then my suggestion with post-processing the output from tar won't work.  In that case, you have to "fix" tar to display the full output, like using gnu tar.  Another option would be to write your own version of tar.  In python, that is very easy, since there is a tar file module, which can read tar files (even compressed) directly.  It would probably take half an hour and 20 lines to write a version of "tar" that can only make a listing in python, but I don't have that half hour tonight.


----------

