5

I have a directory with files coming for every day. Now I want to zip those files group by dates. Is there anyway to group/list the files which landed in same date.

Suppose there are below files in a directory

-rw-r--r--. 1 anirban anirban    1598 Oct 14 07:19 hello.txt
-rw-r--r--. 1 anirban anirban    1248 Oct 14 07:21 world.txt
-rw-rw-r--. 1 anirban anirban  659758 Oct 14 11:55 a
-rw-rw-r--. 1 anirban anirban    9121 Oct 18 07:37 b.csv
-rw-r--r--. 1 anirban anirban     196 Oct 20 08:46 go.xls
-rw-r--r--. 1 anirban anirban    1698 Oct 20 08:52 purge.sh
-rw-r--r--. 1 anirban anirban   47838 Oct 21 08:05 code.java
-rw-rw-r--. 1 anirban anirban 9446406 Oct 24 05:51 cron
-rw-rw-r--. 1 anirban anirban  532570 Oct 24 05:57 my.txt
drwxrwsr-x. 2 anirban anirban      67 Oct 25 05:05 look_around.py
-rw-rw-r--. 1 anirban anirban   44525 Oct 26 17:23 failed.log

So there are no way to group the files with any suffix/prefix, since all are unique. Now when I will run the command I am seeking I will get a set of lines like below based on group by dates.

[ [hello.txt world.txt a] [b.csv] [go.xls purge.sh] [code.java] ... ] and so on.

With that list I will loop through and make archive

tar -zvcf Oct_14.tar.gz hello.txt world.txt a
5
  • Please edit your question and show us an example directory with some files and explain what you would like to happen to them. It is hard to understand exactly what you need without an example. For instance, what's the "same date"? Same day? Same minute? Second? Year?
    – terdon
    Oct 27, 2016 at 16:25
  • The most important question is, are the dates part of the filenames? If they are, you can solve this using shell globs; if not, you can use find with the -mtime primary.
    – Wildcard
    Oct 27, 2016 at 18:59
  • @Wildcard edited my question. Oct 27, 2016 at 19:38
  • Is there any reason you can't just zip all the new files every day, with a cron job?
    – Wildcard
    Oct 27, 2016 at 20:32
  • @Wildcard Yes cron job is the requirement, but that job will run every 30 days. Hence can't zip files everyday. Oct 28, 2016 at 19:32

3 Answers 3

3

With zsh, using an associative array whose keys are the dates and values the NUL-delimited list of files last modified on that date:

zmodload -F zsh/stat b:zstat
typeset -A files
for file (./*) {
  zstat -LA date -F %b_%d +mtime $file &&
    files[$date]+=$file$'\0'
}
for date (${(k)files})
  echo tar zcvf $date.tar.gz ${(0)files[$date]}

Remove the echo when happy.

Note that the month name abbreviations (%b strftime format) will be in the current locale's language (Oct on an English system, Okt on a German one, etc.). To always make it English names regardless of the user's locale, force the locale to C with LC_ALL=C zstat....

With GNU tools, you could do the equivalent with:

find . ! -name . -prune ! -name '.*' -printf '%Tb_%Td:%p\0' |
  awk -v RS='\0' -F : -v q=\' '
    function quote(s) {
      gsub(q, q "\\" q q, s)
      return q s q
    }
    {
      date=$1
      sub(/[^:]*:/, "", $0)
      files[date] = files[date] " " quote($0)
    }
    END {
      for (date in files)
        print "tar zcvf " quote(date ".tar.gz") files[date]
    }'

Pipe to sh when happy.

4
  • zmodload command not found. Oct 27, 2016 at 21:25
  • @AnirbanNag'tintinmj', when I say with zsh, I mean that it's code intended for the zsh shell. You need to enter that code at the prompt of zsh, (not tcsh, ksh, bash or whatever other shell you're using) or in a script interpreted by zsh (for instance with a #! /bin/zsh - shebang). Oct 27, 2016 at 21:28
  • Ok! So this is working as expected so I added tar -zvcf quote(date ".tar.gz") files[date] after print and this should be doing the magic. But I dont know why tar is not happening. Oct 28, 2016 at 20:11
  • Also some comment would help what is doing what. Oct 28, 2016 at 20:16
2
while read date a b filename; do 
    zip -g ../$date.zip "$filename"
done <<< $(stat -c "%y %n" *)
1
  • Error : zip warning: ../2016-10-28.zip not found or empty and zip error: Nothing to do! (../2016-10-28.zip) Oct 29, 2016 at 15:40
-1

Probably I misunderstood the question, but

ls -ls |grep 'Oct 26' > oct26.list

will give the list of files for Oct 26; the same could be done e. g. with hours by using extra grep "| grep 09:" etc. Then do with the list oct26.list whatever you need.

3
  • Correct I was going for that, but how to automate this so code will get 'Oct 26', 'Oct 27' and so on... Oct 28, 2016 at 19:34
  • Oh, I see... But then, I think a little script can loop through all the dates from the 1-st of the current month till current date...
    – Al Kap
    Oct 29, 2016 at 7:47
  • What if a file's name contains Oct 26? What if a file's name contains a newline? More importantly, this won't give you a list of file names! it will give you a list of lines like -rw-rw-r--. 1 anirban anirban 532570 Oct 24 05:57 my.txt. How do you get the file name from that? Remember that file names can have spaces.
    – terdon
    Oct 29, 2016 at 12:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .