Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash/DOS/PowerShell script to list most recent versions of files?

We have a list of (let's say 50) reports that get dumped into various folders depending on certain conditions. All the reports have standard names eg. D099C.LIS, D18A0.LIS etc.

Sometimes a report can exist in up to 5 different locations, and I need to generate a list of all the locations of the most recent version of each report.

I can do it easily using code, or redirecting "dir" or "ls" output into a text file and then manipulating it in Excel, but I'd prefer a simpler (hopefully a one-liner) solution either using DOS, bash, or PowerShell.

The best I've come up with so far in PowerShell (I've done something similar using bash) is:

ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | select Directory, Name, lastwritetime

That will recursively list all files with *.lis extension, then sort it by name (asc) and date (desc), and then display the directory, name, and date.

This gives this sort of output:

C:\reports\LESE            D057A.LIS                  28/01/2009 09:00:43
C:\reports\JCSW            D057A.LIS                  27/01/2009 10:50:21
C:\reports\ALID            D075A.LIS                  04/02/2009 12:34:12
C:\reports\JCSW            D075B.LIS                  05/02/2009 10:07:15
C:\reports\ALID            D075B.LIS                  30/01/2009 09:14:57
C:\reports\BMA3            D081A.LIS                  01/09/2008 14:51:36

What I obviously need to do now is remove the files that aren't the most recent versions, so that the output looks like this (not too worried about formatting yet):

C:\reports\LESE            D057A.LIS                  28/01/2009 09:00:43
C:\reports\JCSW            D075B.LIS                  05/02/2009 10:07:15
C:\reports\BMA3            D081A.LIS                  01/09/2008 14:51:36

Anyone have any ideas?

[edit] Some good ideas and answers to this question. Unfortunately I can't mark all as accepted, but EBGreen's (edited) answer worked without modification. I'll add working solutions here as I verify them.

bash:

 ls -lR --time-style=long-iso | awk 'BEGIN{OFS="\t"}{print $5,$6,$7,$8}' | grep ".LIS" | sort -k4 -k2r -k3r | uniq -f3
 ls -lR --time-style=long-iso | awk 'BEGIN{OFS="\t"}{print $5,$6,$7,$8}' | grep ".LIS" | sort -k4 -k2r -k3r | awk '!x[$4]++'

PowerShell:

  ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | select Directory, Name, lastwritetime | Group-Object Name | %{$_.Group | Select -first 1}
  ls -r . *.lis | sort -desc LastWriteTime | group Name | %{$_.Group[0]} | ft Directory,Name,LastWriteTime
  ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | unique | ft Directory,Name,LastWriteTime
like image 434
ilitirit Avatar asked Feb 06 '09 14:02

ilitirit


2 Answers

ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | select Directory, Name, lastwritetime | Group-Object Name | %{$_.Group | Select -first 1}
like image 165
EBGreen Avatar answered Nov 15 '22 05:11

EBGreen


In bash you could pipe your answers through uniq. I'm not sure of the exact structure for the results of your bash 1-liner but the right arguments to -w N and -s N ought to do it.

like image 22
Nick Fortescue Avatar answered Nov 15 '22 06:11

Nick Fortescue