Reputation: 5387
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
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