4

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
  • 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 '16 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 '16 at 18:59
  • @Wildcard edited my question. – Anirban Nag 'tintinmj' Oct 27 '16 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 '16 at 20:32
  • @Wildcard Yes cron job is the requirement, but that job will run every 30 days. Hence can't zip files everyday. – Anirban Nag 'tintinmj' Oct 28 '16 at 19:32
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.

| improve this answer | |
  • zmodload command not found. – Anirban Nag 'tintinmj' Oct 27 '16 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). – Stéphane Chazelas Oct 27 '16 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. – Anirban Nag 'tintinmj' Oct 28 '16 at 20:11
  • Also some comment would help what is doing what. – Anirban Nag 'tintinmj' Oct 28 '16 at 20:16
2
while read date a b filename; do 
    zip -g ../$date.zip "$filename"
done <<< $(stat -c "%y %n" *)
| improve this answer | |
  • Error : zip warning: ../2016-10-28.zip not found or empty and zip error: Nothing to do! (../2016-10-28.zip) – Anirban Nag 'tintinmj' Oct 29 '16 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.

| improve this answer | |
  • Correct I was going for that, but how to automate this so code will get 'Oct 26', 'Oct 27' and so on... – Anirban Nag 'tintinmj' Oct 28 '16 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 '16 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 '16 at 12:26

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.