Finding files based on date, without using `find`

1

1

I know find can do what I am looking for, but I am wondering if there is an alternative way to find files on the filesystem either created before/after a certain point, or at a certain time.

Typically I rely on updatedb & locate for most of my file searching needs. Issues with those tools, though, are that it only has directory and file names, and it only creates a database of local directories, not anything mounted via CIFS|NFS or via -o loop (eg, .iso images).

So if I need to find files created after yesterday across the entire system (local and remote filesystems), I am currently needing to use find.

What other tools, if any, would accomplish this in a similar fashion?

I have tried ls and grep, but that requires (in my attempts so far) multiple searches:

ls -lR | grep Aug | grep 10
ls -lR | grep Aug | grep 11

warren

Posted 2011-08-11T14:55:15.400

Reputation: 8 599

3why do you not want to use find? – Heisenbug – 2011-08-11T15:05:47.337

@0verbose - for an alternative – warren – 2011-08-11T17:38:04.247

alias lookfor='find' might do the trick. (I'm kidding, of course.) – nhinkle – 2011-08-11T17:45:13.160

1@Nifle: you could cut you meat with an axe, but careful to the plate. I think scissors might also be a solution, and they might be safer in planes. Sometimes, I cut my burger meat with a fork to avoid having to wash a knife (I am a programmer, so I am also lazy). And if I am really hungry and out of knife, I might cut my steak with my teeth. :-) – jfg956 – 2011-08-11T17:55:24.770

Answers

1

You could customize the timestamp output of ls to be more easily understandable:

ls -ln --time-style="+%Y%m%d%H%M%N"

and then, comparing dates is as easy to compare strings. You would have to do this with awk:

ls -ln --time-style="+%Y%m%d%H%M%N" | tail -n +2 | awk -F " " '$6 > "201108100000000000000" {$1=$2=$3=$4=$5=$6=""; print substr($0, 7)}'

Be careful to use the right -a or -c option for the right time of the file.

And remember that ctime it not creation time, it is the time of the inode change (creation, permission, file size change, ...).

Edit:

awk can even be avoided:

ls -ln --time-style="+%Y%m%d%H%M%N" | tail -n +2 | \
while read perms inode user group size date file; do
  if [ $date > "201108100000000000000" ]; then
    printf "%s\n" "$file"
  fi
done

jfg956

Posted 2011-08-11T14:55:15.400

Reputation: 1 021

1

you can use alternatives with egrep:

ls -lR | egrep "Aug *10|Aug *11"

Michał Šrajer

Posted 2011-08-11T14:55:15.400

Reputation: 2 495

Or egrep "Aug 1[01]" – RedGrittyBrick – 2011-08-11T15:31:33.153

1

I would like to ask why you don't want to use find, but I don't think I really want to know ...

I'd try with awk:

ls -lR | awk '{ d="^2011-0[78]"; if ($6 ~ d){ print $0 }}'

d in command is regual expression.
Then the 6th column from ls output is evaluated with provided regex and the whole row printed only if it does.
On my system date is in format of yyyy-mm-dd hh:mi and with regex I was searching for Jul and Aug files. Alter regex to your needs.

Also to add why I chose awk: you could replace print $0 with print $8 and you only get the file name on output - with grep regex would be a mess ...

nEJC

Posted 2011-08-11T14:55:15.400

Reputation: 128

1

for one single command quick to type, i'm not sure, you may be better off with a script doing one tricky line, or multiple. There's this line, which uses a regex
$ls -lR | grep -E "2011-08-1[01]"
A regex like a[bc] means a followed by b or c. So 1[01] covers 10 and 11. You could do 1[0-3] for 10-13 though we're not on the date of 13th yet as of writing. This would be 07 or 08 or 09 or 10 or 11... 13. 0[7-9]|1[0123] .

barlop

Posted 2011-08-11T14:55:15.400

Reputation: 18 677

1

You could use the -nt and -ot build in bash tests. From the bash manual:

file1 -nt file2: True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.

file1 -ot file2: True if file1 is older than file2, or if file2 exists and file1 does not.

To create you test temporary file, you can use touch.

To loop through the files in a directory, you can use shell expansion and bash build in bash tests for directory testing (-d file). But be careful about link loops in the filesystem.

jfg956

Posted 2011-08-11T14:55:15.400

Reputation: 1 021

1

You could create a temporary file with the timestamp of your search, and then use the sorting option of ls: the files you are looking for would be before (or after) the temporary file.

File splitting (or ls output splitting) is discussed in Linux file spliting.

jfg956

Posted 2011-08-11T14:55:15.400

Reputation: 1 021