5

我们有一个列表(比如说 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]++'

电源外壳:

  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
4

8 回答 8

8
ls -r -fi *.lis | sort @{expression={$_.Name}}, @{expression={$_.LastWriteTime};Descending=$true} | select Directory, Name, lastwritetime | Group-Object Name | %{$_.Group | Select -first 1}
于 2009-02-06T14:27:14.770 回答
2

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

于 2009-02-06T14:43:01.400 回答
2

PowerShell 中的另一种选择,更多“脚本”,例如:

ls -r . *.lis | sort LastWriteTime | %{$f=@{}} {$f[$_.Name]=$_} {$f.Values} | ft Directory,Name,LastWriteTime
  1. 递归获取文件
  2. 按上次写入时间升序排序
  3. 初始化哈希图(关联数组)
  4. 对于每个文件,使用名称作为键分配它 - 以后的条目将覆盖以前的条目
  5. 获取哈希图的值(不包括键)
  6. 格式为表格

请注意,FileInfo 对象在整个管道中保留。您仍然可以访问对象的任何属性/方法或以任何您喜欢的方式对其进行格式化。

于 2009-03-05T19:28:54.977 回答
1

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

寻找 。-名称“*.lis”-打印| xargs ls -tr | awk -F/ '!x[$NF]++'

于 2009-02-06T14:55:39.160 回答
1

电源外壳:

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

解释:

  1. 递归获取文件
  2. 按 LastWriteTime 降序对文件进行排序
  3. 按名称对文件进行排序,选择唯一文件(仅第一个)。
  4. 使用目录、名称和时间在表格中格式化生成的 FileInfo 对象

不依赖排序稳定的替代方案:

ls -r . *.lis | sort -desc LastWriteTime | group Name | %{$_.Group[0]} | ft Directory,Name,LastWriteTime
  1. 递归获取文件
  2. 按 LastWriteTime 降序对文件进行排序
  3. 按名称对文件进行分组
  4. 为每个组选择该组的第一个(索引零)项目
  5. 使用目录、名称和时间在表格中格式化生成的 FileInfo 对象
于 2009-03-04T22:06:38.957 回答
0

你能用perl吗?就像是:

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

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

于 2009-02-06T14:47:26.167 回答
0

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

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

于 2010-07-15T00:24:11.157 回答
-1

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

# remove -whatIf 删除文件

$f[1..$f.length] | 删除项目 -whatIf

于 2009-02-07T16:17:39.183 回答