2017-08-01 52 views
-2

如何从目录中获取重复文件?我想忽略文件的版本号。我想要httpcore作为回报。 我能想到的最简单的方法是从shell目录中获取重复文件

allfiles <-- readAllFileNames() 
for file1 in allfiles 
    for file2 in allfiles 
     compare file1 and file2 by ignoring version 

是否有任何其他有效的方法?

+1

您将“复制”定义为“多个文件,如果您从名称中删除了版本号,将具有相同的名称”?你如何定义版本号?有很多版本编号方案,对'4.3'有效的东西不一定会抓住'4.3.1'或'4.3rc1'什么的。 –

+0

如果您从名称中删除了版本号,会有相同的名称“? - >是的。我正在处理你提到的漂亮的版本号。 – sattu

+0

为每个文件生成一次校验和 - 查找重复的校验和。 –

回答

0

你可以做这样的事情与seduniq如果你可以定义一个正则表达式匹配一个版本号:

ls | sed -r 's/(v?-[[:digit:]].*)?\.[[:alpha:]]+$//' | uniq --repeated 

这个特殊的正则表达式匹配任何一个连字符后面跟着一个数字(假设是这样的开始一个版本号),并且在任何情况下匹配文件扩展名,并将其删除。

$ ls -Fl 
total 0 
-rw-rw-r--. 1 dhouck dhouck 0 Aug 2 10:28 httpcore-4.3.jar 
-rw-rw-r--. 1 dhouck dhouck 0 Aug 2 10:28 httpcore.jar 
-rw-rw-r--. 1 dhouck dhouck 0 Aug 2 10:28 http.jar 
$ ls | sed -r 's/(v?-[[:digit:]].*)?\.[[:alpha:]]+$//' | uniq --repeated 
httpcore 

这里的sed命令做什么,在细节,如果你要改变它:

  • -r:使用扩展的正则表达式,这使得它更容易使用 一些花哨的东西下面。
  • s/ ... / ... /:开始“替代”命令。将第一个和第二个斜线之间的所有内容作为正则表达式,并将其替换为第二个和第三个斜线之间的内容。在这种情况下,第二个和第三个斜线之间没有任何内容,所以这只是摆脱了所有匹配的内容。
  • ( ... )?:圆括号组成一个组,因此它们之间的所有内容都被视为一个单元。问号表示该组是可选的。这是针对可能不存在的版本号。

    • -:匹配一个字面-字符,因为版本号通常是从其他一切连字符掀起。
    • v?:可选地匹配字符v,因为有时在版本号之前使用该字符。如果你有一些名为javascript-v8-6.0.jar或其他的东西,你可能想删除它。
    • [[:digit:]]:匹配一个数字。
    • .*:本.匹配任何字符,*

    总之,这些都表明了一个版本号是第一个连字符后面跟着一个数字后,任何东西。这适用于package-3.2-beta-1.jar的情况,但在graphics-3d-7.1的情况下不会匹配太多。

  • 未分组在正则表达式中的下一个部分用于文件扩展名。看来你也想删除它;如果不这样做,请将下面的内容放在括号中,而不是空替换(第二个和第三个斜线之间的部分),使用\2,这意味着“捕获组2”的内容。版本将是第一个捕获组,并且包括版本和扩展名的整个匹配表达式将是组0.
    • \.:匹配文字.。如上所述,因为.本身就匹配任何内容,所以需要反斜杠。
    • [[:alpha:]]:匹配任何字母
    • +:你以前的部分([[:alpha:]])一次或多次。这允许.o.sh.jar.java.class扩展等
  • $:锚在该行(文件名)的末尾。这可以确保在某个文件名的中间不会出现假冒的“扩展名”。

uniq --repeated将采取所有这些行,并告诉你哪些是重复的。它需要排序输入,但ls的输出已排序,sed脚本不应更改该值。