在Linux中,如何找到存在于同一目录中的同名但情况不同的重复文件?
如何返回名为重复的文件列表,即具有相同名称但在不同情况下存在于同一目录中的文件列表 我不在乎文件的内容。我只需要知道任何具有相同名称副本的文件的位置和名称 重复示例:在Linux中,如何找到存在于同一目录中的同名但情况不同的重复文件?,linux,bash,command-line,find,filesystems,Linux,Bash,Command Line,Find,Filesystems,如何返回名为重复的文件列表,即具有相同名称但在不同情况下存在于同一目录中的文件列表 我不在乎文件的内容。我只需要知道任何具有相同名称副本的文件的位置和名称 重复示例: /www/images/taxi.jpg /www/images/Taxi.jpg 理想情况下,我需要从基本目录递归搜索所有文件。在上面的示例中,它是/www/请尝试: ls -1 | tr '[A-Z]' '[a-z]' | sort | uniq -c | grep -v " 1 " 很简单,真的:-)管道不是很棒的野兽吗
/www/images/taxi.jpg
/www/images/Taxi.jpg
理想情况下,我需要从基本目录递归搜索所有文件。在上面的示例中,它是/www/
请尝试:
ls -1 | tr '[A-Z]' '[a-z]' | sort | uniq -c | grep -v " 1 "
很简单,真的:-)管道不是很棒的野兽吗
ls-1
每行为您提供一个文件,tr'[A-Z]'[A-Z]
将所有大写字母转换为小写字母,sort
对它们进行排序(令人惊讶),uniq-c
删除随后出现的重复行,同时也为您提供一个计数,最后,grep-v“1”
去掉计数为1的行
当我在一个有一个“副本”的目录中运行这个时(我将qq
复制到qq
),我得到:
对于“this directory and every subdirectory”(此目录和每个子目录)版本,只要将ls-1
替换为find.
或find DIRNAME
,如果需要特定的目录起点(DIRNAME
是您想要使用的目录名)
这(对我来说)返回:
这是由于:
pax> ls -1d .gnome2/accels/[bB]* .gconf/system/gstreamer/0.10/audio/profiles/[mM]* [qQ]?
.gconf/system/gstreamer/0.10/audio/profiles/mp3
.gconf/system/gstreamer/0.10/audio/profiles/MP3
.gnome2/accels/blackjack
.gnome2/accels/Blackjack
qq
qQ
更新: 实际上,经过进一步思考,
tr
将把路径的所有组件都小写,以便
/a/b/c
/a/B/c
将被视为重复,即使它们位于不同的目录中
如果您只希望单个目录中的重复项显示为匹配项,则可以使用(非常可怕):
代替:
tr '[A-Z]' '[a-z]'
它所做的只是将路径名的最后部分小写,而不是整个路径名。此外,如果您只需要常规文件(没有目录、FIFO等),请使用
find-typef
来限制返回的内容。另一个答案很好,但不是我建议的“相当可怕”的perl脚本
perl -pe 's!([^/]+)$!lc $1!e'
它将仅将路径的文件名部分小写
编辑1:事实上,整个问题可以通过以下方式解决:
find . | perl -ne 's!([^/]+)$!lc $1!e; print if 1 == $seen{$_}++'
编辑3:我发现了一个使用sed、sort和uniq的解决方案,该解决方案也将打印出副本,但它仅在文件名中没有空格时才起作用:
find . |sed 's,\(.*\)/\(.*\)$,\1/\2\t\1/\L\2,'|sort|uniq -D -f 1|cut -f 1
编辑2:这里有一个较长的脚本,它将打印出名称,它采用stdin上的路径列表,如
find
所示。不那么优雅,但仍然:
#!/usr/bin/perl -w
use strict;
use warnings;
my %dup_series_per_dir;
while (<>) {
my ($dir, $file) = m!(.*/)?([^/]+?)$!;
push @{$dup_series_per_dir{$dir||'./'}{lc $file}}, $file;
}
for my $dir (sort keys %dup_series_per_dir) {
my @all_dup_series_in_dir = grep { @{$_} > 1 } values %{$dup_series_per_dir{$dir}};
for my $one_dup_series (@all_dup_series_in_dir) {
print "$dir\{" . join(',', sort @{$one_dup_series}) . "}\n";
}
}
#/usr/bin/perl-w
严格使用;
使用警告;
我的%dup\u系列\u每个\u目录;
而(){
我的($dir,$file)=m!(.*/)?([^/]+?)$!;
push@{$dup_series_per_dir{$dir | | |'./'}{lc$file},$file;
}
对于我的$dir(排序键%dup\u series\u per\u dir){
我的@all_dup_series_in_dir=grep{{{$}>1}值%{$dup_series_per_dir{$dir};
对于我的$one_dup_系列(@all_dup_series_in_dir){
打印“$dir\{”.join(',',sort@{$one_dup_series})。“}\n”;
}
}
我相信
ls | sort -f | uniq -i -d
更简单、更快,并且在mpez0响应之后将给出相同的结果,以递归方式检测,只需将“ls”替换为“find”。 我看到的唯一问题是,如果这是一个正在复制的目录,那么这个目录中的每个文件都有一个条目。需要一些人脑来处理这个过程的输出 但无论如何,你不会自动删除这些文件,是吗
find . | sort -f | uniq -i -d
这是一个很好的小命令行应用程序,名为
findsn
,如果您编译deb包不包含的fslint
,就会得到它
它可以找到任何同名的文件,而且速度极快,可以处理不同的情况
/findsn --help
find (files) with duplicate or conflicting names.
Usage: findsn [-A -c -C] [[-r] [-f] paths(s) ...]
如果未提供任何参数,将搜索$PATH以查找任何冗余参数
或冲突文件
-A reports all aliases (soft and hard links) to files.
If no path(s) specified then the $PATH is searched.
如果只指定了路径,则会检查它们是否存在重复的命名路径
文件夹。您可以在此搜索中使用-C限定此项以忽略大小写。
使用-c进行限定更具限制性,因为只有文件(或目录)
在同一目录中,其名称仅在报告大小写时有所不同。
I.E.-c将标记在传输时会发生冲突的文件和目录
到不区分大小写的文件系统。注意如果指定了-c或-c,以及
假定当前目录未指定任何路径。以下是如何查找所有重复jar文件的示例:
find . -type f -printf "%f\n" -name "*.jar" | sort -f | uniq -i -d
将
*.jar
替换为您正在寻找的任何重复文件类型。这里有一个适合我的脚本(我不是作者)。原文和讨论可在此处找到:
如果find命令不适用于您,您可能需要更改它。比如说
OLD : find "${1}" -type f | xargs -n 1 basename
NEW : find "${1}" -type f -printf "%f\n"
您可以使用:
find -type f -exec readlink -m {} \; | gawk 'BEGIN{FS="/";OFS="/"}{$NF=tolower($NF);print}' | uniq -c
其中:
查找-类型f
递归打印所有文件的完整路径-exec readlink-m{}代码>
获取文件的绝对路径gawk'BEGIN{FS=“/”OFS=“/”}{$NF=tolower($NF);print}
将所有文件名替换为小写uniq-c
唯一路径,-c输出重复的计数
yum install fdupes
这一次有点晚了,但这是我的版本:
find . -type f | awk -F/ '{print $NF}' | sort -f | uniq -i -d
这里我们使用:
查找
-查找当前目录下的所有文件awk
-删除文件名的文件路径部分排序
-不敏感地排序大小写uniq
-从管道中找到复制品(受@mpez0-answer和@SimonDowdles对@paxdiablo-answer的评论启发。)您可以使用GNU awk检查给定目录中的重复项:
gawk 'BEGINFILE {if ((seen[tolower(FILENAME)]++)) print FILENAME; nextfile}' *
这用于在继续读取文件之前执行某些操作。在本例中,它跟踪出现在数组seen[]
中的名称,该数组的索引是l中的文件名
find -type f -exec readlink -m {} \; | gawk 'BEGIN{FS="/";OFS="/"}{$NF=tolower($NF);print}' | uniq -c
yum install fdupes
find . -type f | awk -F/ '{print $NF}' | sort -f | uniq -i -d
gawk 'BEGINFILE {if ((seen[tolower(FILENAME)]++)) print FILENAME; nextfile}' *
$ tree
.
├── bye.txt
├── hello.txt
├── helLo.txt
├── yeah.txt
└── YEAH.txt
0 directories, 5 files
$ gawk 'BEGINFILE {if ((a[tolower(FILENAME)]++)) print FILENAME; nextfile}' *
helLo.txt
YEAH.txt