2

I have a set of files in a structure like so;

regions ├── ap-northeast-1 │   └── sg-66497903 │   ├── sg-66497903-2017-10-03-Tue-12.39.json │   ├── sg-66497903-2017-10-03-Tue-12.42.json │   ├── sg-66497903-2017-10-03-Tue-12.49.json │   ├── sg-66497903-2017-10-03-Tue-12.53.json │   └── sg-66497903-2017-10-03-Tue-13.12.json ├── ap-northeast-2 │   └── sg-824282eb │   ├── sg-824282eb-2017-10-03-Tue-12.39.json │   ├── sg-824282eb-2017-10-03-Tue-12.42.json │   ├── sg-824282eb-2017-10-03-Tue-12.49.json │   ├── sg-824282eb-2017-10-03-Tue-12.53.json │   └── sg-824282eb-2017-10-03-Tue-13.12.json ├── ap-south-1 │   └── sg-4fec0526 │   ├── sg-4fec0526-2017-10-03-Tue-12.39.json │   ├── sg-4fec0526-2017-10-03-Tue-12.42.json │   ├── sg-4fec0526-2017-10-03-Tue-12.49.json │   ├── sg-4fec0526-2017-10-03-Tue-12.53.json │   └── sg-4fec0526-2017-10-03-Tue-13.12.json 

The list is longer but you get the idea. I am trying to find the oldest json file in each directory to use as at the standard to set in an array and diff the other files in the individual directories.

I have this so far, but it's not right.

#!/bin/bash mapfile -t awsReg < <(ls ~/regions) for awsrg in "${awsReg[@]}" do mapfile -t awsSG < <(ls regions/"$awsrg") for sg in "${awsSG[@]}" do find "$sg" -mindepth 2 -type f -printf '%T+ %p\n' | sort | head -n 1 diff -q ##oldest file## ##all other files### done done 

For example I would like in regions -> ap-northeast-1 -> sg-66497903 to find the file sg-66497903-2017-10-03-Tue-12.39.json, set it as the file to diff the other files in the directory with a diff -q. Move on to next directory, find the oldest in that directory....etc

1
  • 1
    Why don't you just use ls -tQ | tail -1 to get the olders file?CommentedOct 4, 2017 at 9:21

3 Answers 3

1

It's a lot easier in zsh:

for sg in ~/region/ap-*/sg-*(/); do files=($sg/sg-*.json(N.Om)) # list of json regular files sorted # from oldest to newest if (($#files >= 2)); then oldest=$files[1] files[1]=() for file in $files; do cmp -s $oldest $file || printf '"%s" differs from "%s"\n' $file $oldest done fi done 

With ksh93 or bash and GNU ls, you could translate that to:

for sg in ~/region/ap-*/sg-*/; do eval "files=($(ls --quoting-style=shell-always -rtd -- "$sg"sg-*.json))" if ((${#files[@]} >= 2)); then oldest=${files[1]} files=("${files[@]:1}") for file in "${files[@]}"; do cmp -s "$oldest" "$file" || printf '"%s" differs from "%s"\n' "$file" "$oldest" done fi done 
3
  • bash is complaining about the * (asterisk) in the for path. Can I incorporate them into an array?
    – eekfonky
    CommentedOct 4, 2017 at 13:11
  • @eekfonky, not sure what you mean, there's no reason why bash would complain about * there. Are you saying that that glob doesn't match any file?CommentedOct 4, 2017 at 15:40
  • Yes, it doesn't like the glob. I figured it out. I have many more directories without the 'ap'. My mistake
    – eekfonky
    CommentedOct 4, 2017 at 15:43
1

Well you have the file very well named - from most significant value to least so even simple text sort will do it In each directly you can do in bash

myfile=$(ls -1 *.json| sort | head -1) 

this will set your variable $myfile to what you need and diff-away as much as you need

to get the other files all but your myfile

ls -1 *.json | grep -v $myfile 
    1

    The proper way would be to use something like:

     #!/usr/bin/env bash unset -v oldest oldest() { local files f old; files=("${1:-.}"/*) old="${files[0]}" for f in "${files[@]}" do [[ $f -ot $old ]] && old=$f ;done printf '%s\n' "$old" } 

    Call the script as in: ./oldest regions/*

      You must log in to answer this question.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.