Bash / DOS / PowerShell脚本列出最新版本的文件?

时间:2009-02-06 14:20:33

标签: bash powershell shell dos

我们有一个(比方说50个)报告列表,这些报告会根据特定条件转储到各种文件夹中。所有报告都有标准名称,例如。 D099C.LIS,D18A0.LIS等。

有时,报告最多可以存在于5个不同的位置,我需要生成每个报告的最新版本的所有位置的列表。

我可以轻松地使用代码,或者将“dir”或“ls”输出重定向到文本文件然后在Excel中进行操作,但我更喜欢使用DOS的更简单(希望是单行)解决方案,bash或PowerShell。

到目前为止,我在PowerShell中做到的最好(我使用bash做了类似的事情)是:

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

将以递归方式列出所有带* .lis扩展名的文件,然后按名称(asc)和日期(desc)对其进行排序,然后显示目录,名称和日期。

这给出了这种输出:

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

我现在显然需要做的是删除不是最新版本的文件,以便输出看起来像这样(不太担心格式化):

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

有人有什么想法吗?

[编辑] 一些好的想法和这个问题的答案。不幸的是,我不能将所有标记都接受,但EBGreen的(编辑过的)答案无需修改即可。我会在验证它们时添加工作解决方案。

击:

 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

8 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:2)

在bash中,您可以通过uniq传达答案。我不确定你的bash 1-liner的结果的确切结构,但-w N和-s N的正确参数应该这样做。

答案 2 :(得分:2)

PowerShell中的另一种替代方案,更像“脚本”,如:

ls -r . *.lis | sort LastWriteTime | %{$f=@{}} {$f[$_.Name]=$_} {$f.Values} | ft Directory,Name,LastWriteTime
  1. 以递归方式获取文件
  2. 按上次写入时间升序排序
  3. 初始化散列图(关联数组)
  4. 为每个文件使用名称作为键分配它 - 后面的条目将覆盖以前的条目
  5. 获取hashmap的值(不包括键)
  6. 格式化为表格
  7. 注意,FileInfo对象在整个管道中保留。您仍然可以访问对象的任何属性/方法或以您喜欢的方式格式化它们。

答案 3 :(得分:1)

问题似乎是根据特定领域找到独特的。 awk可以用来解决这个问题。看到这个blog entry有一种方法。 例如,在bash中可以做到:

找到。 -name“* .lis”-print | xargs ls -tr | awk -F /'!x [$ NF] ++'

答案 4 :(得分:1)

Powershell的:

ls -r . *.lis | sort -desc LastWriteTime | sort -u Name | ft Directory,Name,LastWriteTime

说明:

  1. 以递归方式获取文件
  2. 按LastWriteTime降序排序的文件
  3. 按名称对文件进行排序,选择唯一文件(仅限第一个)。
  4. 在包含目录,名称和时间的表中格式化生成的FileInfo对象
  5. 不依赖排序稳定的替代方案:

    ls -r . *.lis | sort -desc LastWriteTime | group Name | %{$_.Group[0]} | ft Directory,Name,LastWriteTime
    
    1. 以递归方式获取文件
    2. 按LastWriteTime降序排序的文件
    3. 按名称对文件进行分组
    4. 为每个组选择组
    5. 的第一个(索引零)项
    6. 在包含目录,名称和时间的表中格式化生成的FileInfo对象

答案 5 :(得分:0)

你能用perl吗?类似的东西:

你的命令 | perl'while(< STDIN>){($ dir,$ name,$ date)= split; $ hash {$ name} =($ dir,$ date);} foreach(keys%hash){print“$ hash {$ } [0] $ $ hash {$ _} [1] \ n“; }“

这在细节上可能是错误的(因为我在愤怒中使用了perl已经太长了)但基本的想法是保持结果的哈希值键入文件名并且在遇到新条目时总是覆盖前一个条目。这样,只要输入的行的顺序正确,您将只获得最近触及的文件。

答案 6 :(得分:0)

ls -ARFlrt | awk'{print $ 6,$ 7,$ 8}'| grep 2010 | sort -n

正在寻找类似的。以上帮助我获得了我在bash中的列表。 grep是可选的(当然)。 \感谢

答案 7 :(得分:-1)

$ f = ls -r -fi * .lis |排序名称,lastWriteTime -desc

#remove -whatIf删除文件

$ f [1 .. $ f.length] | Remove-Item -whatIf