If you want to find regular files that are more than 10 days old and that have been last modified on a Saturday (in the timezone of the user running the script), with GNU tools (and you seem to be on a GNU system as you're using a GNU-specific option to date
and the GNU shell), you can do:
find . -type f -mtime +10 -printf '%Tu%p\0' |
sed -zn 's/^6//p' |
tr '\0' '\n'
While GNU eventually added (yet a different) stat
command in the early 2000s to query file metadata in a more scriptable fashion that with ls
, most of its functionality was already in GNU find
long before that and with a much better interface than GNU stat
's.
Most other stat
implementations can give you the modification time in any format, GNU stat
can't (the reason why you end up resorting to a combination of ls
and GNU date
in your question I suppose) but GNU find
can (with GNU date
, you could also use date -r "$file" +%u
).
Above %T<format-letter>
is the modification time using the specified strftime
format. %Tu
is the day of the week as a number from 1 (Monday) to 7. That's better in scripts than using %a
/%A
that are locale dependant.
We're printing that number followed by the file path, NUL delimited to be able to handle file names with newline characters, and piping to sed
to select the records that start with 6
(and remove that 6 for them). The NULs are then translated to newline on output.
-z
was added to GNU sed
in 2012. If your sed
is older, you can change the above to:
find . -type f -mtime +10 -printf '%Tu%p\0' |
tr '\0\n' '\n\0'
sed -n 's/^6//p' |
tr '\0' '\n'
Generally, you don't want to loop over the output of find
like you do in your question. If you wanted to loop over the files found by find
in bash
, you'd rather do:
while IFS=/ read -d '' -ru3 day file; do
case $day in
(6) printf '"%s" was last modified on a Saturday\n' "$file";;
esac
done 3< <(find . -type f -mtime +10 -printf '%Tu/%p\0')
In zsh
, you could also do:
zmodload zsh/stat # for zsh's stat builtin
last_modified_on_a_saturday() {
local -A stat
stat -LF %u -H stat -- ${1-$REPLY} &&
((stat[mtime] == 6))
}
for file in **/*(ND.m+10+last_modified_on_a_saturday); do
do-something with $file
done
find
's output 2) Don't parse the output ofls
(and as a general rule, don't run a command N times if you need to extract N strings from its output) 3) Learn how to assign the output of a command to a variable - as right now you definitely don't know how to do it. 4) What is the point of ending each line with a semicolon ? 5) "si il a ete créer" – don_crissti Mar 01 '17 at 11:20