SU3
SU3

Reputation: 5387

Filter out files older than another file from a list in bash

Given a list of file names, is there a way to remove the names from the list corresponding to files older than another file?

For example, if I have a string "a b c", and file a is older than file d, but b and c are not, I want to turn the string into "b c".

Edit, since people are asking for the specifics:

I want to reduce code duplication in this chunk of bash script:

for f in $(ls | grep '.json$'); do
  base=$(basename $f .json)
  regex=".*/${base}_[0-9]\{3\}-[0-9]\{3\}\.dat"
  if [ -z "$(find dat -regextype sed -regex ${regex})" ] || \
     [ -n "$(find dat -regextype sed -regex ${regex} -not -newer $f)" ] || \
     [ -n "$(find dat -regextype sed -regex ${regex} -not -newer ../bin/vars)" ]
  then
    echo $f
    ../bin/vars $f -o dat/$base \
      -b 200 250 300 350 400 450 500
  fi
done

Upvotes: 0

Views: 135

Answers (1)

Benjamin W.
Benjamin W.

Reputation: 52152

There is a comparison operator -nt ("newer than") to compare two files. If you have these files:

-rw-r--r-- 1 benjamin staff   0 Jun 20 11:30 a.json
-rw-r--r-- 1 benjamin staff   0 Jun 20 11:34 b.json
-rw-r--r-- 1 benjamin staff   0 Jun 20 11:34 c.json
-rw-r--r-- 1 benjamin staff   0 Jun 20 11:32 d.json

then you can use it as follows:

$ for f in {a,b,c}.json; do [[ $f -nt d.json ]] && echo "$f"; done
b.json
c.json

Wrapped in a function that expects the reference file as the first argument and the list of filenames as the rest of the arguments:

filterfiles () {
    local filtered
    for f in "${@:1}"; do
        [[ $f -nt $1 ]] && filtered+=("$f")
    done
    echo "${filtered[@]}"
}

to be used like

$ filterfiles d.json {a,b,c}.json
b.json c.json

Alternatively, if you just want to know if at least one file is newer than the reference file (as alluded to in comments):

filterfiles () {
    for f in "${@:1}"; do
        [[ $f -nt $1 ]] && return 0
    done
    return 1
}

Now, you can check the return value of the function:

if filterfiles d.json {a,b,c}.json; then echo "Array contains newer file"; fi

Upvotes: 3

Related Questions