Stephan
Stephan

Reputation: 43

Is this a good way to create unique folders based on modified dates?

I have a folder full of images. I'd like to create folders for each based on when that image (or file) was modified. Is this a good way to do that in bash? The code works but I'm still a novice and not sure if there are better ways.

ls -l | sort -k8n -k6M -k7n | tr -s ' ' | cut -d ' ' -f6-8 | uniq | sed '/^$/d'| parallel -j 24 date --date={} +"%Y-%m-%d"| parallel -j 24 mkdir {}

Explanation of code:

  1. ls -l #find files and tell me modified date.
  2. sort -k8n -k6M -k7n # sort values by column 8 (format numeric) then 6 (format is Month) then 7 (format numeric).
  3. tr -s ' ' # truncate all spaces into one spaces.
  4. cut -d ' ' -f6-8 # cut the text by the delimiter " " (i.e., space) and save columns 6-8.
  5. uniq #save only unique values
  6. sed '/^$/d' #remove empty lines.
  7. parallel -j 24 date --date={} +"%Y-%m-%d" #take input and parallel process into 24 jobs. Then convert the date input (coming from {}) into a YYYY-MM-DD format.
  8. parallel -j 24 mkdir {} #create 24 jobs that create folders based on output from previous command ({}).

Upvotes: 1

Views: 359

Answers (1)

Shawn
Shawn

Reputation: 52529

There are a lot of simpler, less error prone ways to do this. If you have the GNU version of date(1), for example:

#!/usr/bin/env bash
shopt -s nullglob
declare -A mtimes
# Adjust pattern as needed
for file in *.{png,jpg}; do
    mtimes[$(date -r "$file" +'%Y-%m-%d')]=1
done
mkdir "${!mtimes[@]}"

This uses a bash associative array to store all the timestamps to use to create new directories from and then makes them all at once with a single mkdir.


And since I mentioned preferring to do it in something other than pure shell in a comment, a tcl one-liner:

tclsh8.6 <<'EOF'
file mkdir {*}[lsort -unique [lmap file [glob -nocomplain -type f *.{png,jpg}] { clock format [file mtime $file] -format %Y-%m-%d }]]
EOF

or perl:

perl -MPOSIX=strftime -e '$mtimes{strftime q/%Y-%m-%d/, localtime((stat)[9])} = 1 for (glob q/*.{png,jpg}/); mkdir for keys %mtimes'

Both of these have the advantage of not needing a specific implementation of date (The -r option isn't POSIX; not sure how widely supported it is outside of the GNU coreutils version), or bash 4+ (An issue if you're using, say, a Mac (I think they still come with perl, at least until the next OS X version or two)).

Upvotes: 1

Related Questions