You are not logged in.

#1 2021-06-16 09:28:48

brontosaurusrex
Middle Office
Registered: 2015-09-29
Posts: 2,381
Website

Sort files/dirs by date and eventually process each

This is just an example, wondering if there is better solution

    #!/bin/bash

    # listByDate

    # list dirs/files by date
    # and do something with each.
    # and do something with newest.

    while read -r path; do

        echo "$path" 
        # do something with $path here
        woot="$path" # For some reason $path is local
        
    done < <( find . -type d  -not -path "." -printf "%T@\t%Tc %p\n" | sort -n | cut -d " " -f 8- )

    # do something with $woot here
    [ -n "$woot" ] && cd "$woot" || exit
    tree --noreport -t | tail -n +2

Example usage

    cd apps
    listByDate

returns

    ./firefox/defaults
    ./firefox/defaults/pref
    ./firefox/browser/chrome
    ./firefox/browser/chrome/icons
    ./firefox/browser/chrome/icons/default
    ./firefox/browser
    ./firefox/browser/features
    ./firefox/fonts
    ./firefox/icons
    ./firefox/gmp-clearkey
    ./firefox
    ./firefox/gmp-clearkey/0.1
    ├── manifest.json
    ├── libclearkey.so
    ├── libclearkey.so.sig
    └── last

I know I needed something similar in scripts at lest 3 times, so comments on how to do this much better are welcome.

Offline

#2 2021-06-17 02:43:34

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 8,324
Website

Re: Sort files/dirs by date and eventually process each

Don't know if these would be any use (in my .bash_aliases).
Feed them a list of files to get the newest or oldest. (-n<number> for second/third newest)
They're generating a sorted list in an array so you could tweak them to output the whole list instead.( maybe 'for f in "${list[@]}"; do echo "${files[$f]}"; done' )

newest(){
    if [[ $1 = '-n'* ]]
    then
        local offset="${1#-n}"
        shift
    else
        local offset=0
    fi
    declare -A files=()
    for i in "$@"
    do
        files[$(stat -c %Y "$i")]="$i"
    done
    local list=($(sort -nr <(printf '%s\n' "${!files[@]}")))
    echo "${files[${list[$offset]}]}"
}

oldest(){
    if [[ $1 = '-n'* ]]
    then
        offset="${1#-n}"
        shift
    else
        offset=0
    fi
    declare -A files=()
    for i in "$@"
    do
        files[$(stat -c %Y "$i")]="$i"
    done
    list=($(sort -n <(printf '%s\n' "${!files[@]}")))
    echo "${files[${list[$offset]}]}"
}

There's also a sorting technique called "bubblesort" (can probably be googled) which I tried on an array some time ago. Don't think I've used it since though. roll
https://forums.bunsenlabs.org/viewtopic … 924#p62924


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

#3 2021-06-17 19:40:36

brontosaurusrex
Middle Office
Registered: 2015-09-29
Posts: 2,381
Website

Re: Sort files/dirs by date and eventually process each

So I'd need to feed it file by file, like

newest file1 file2 file3

?

Offline

#4 2021-06-18 01:08:19

johnraff
nullglob
From: Nagoya, Japan
Registered: 2015-09-09
Posts: 8,324
Website

Re: Sort files/dirs by date and eventually process each

^Yes, or let the shell make the list as:

newest /path/to/directory/*

or even use globstar to go recursive:

shopt -s globstar
newest /path/**
shopt -u globstar

Or get a list from find which gives you more control, but you need to be careful about spaces and odd characters in the filepath. Like, use find's -print0 option, feed the result to mapfile -d '' to make an array and finally newest "${array[@]}"
A simple shell glob lets you avoid all that.

Or, if you do load a bunch of filenames in an array (eg via mapfile) then you might be able to apply that sort function I posted above to it.


...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )

Introduction to the Bunsenlabs Lithium Desktop

Offline

Board footer

Powered by FluxBB