我怎样才能返回名称重复的文件列表,即具有相同的名称,但在不同的情况下,存在于同一目录 ?
我不在乎文件的内容。 我只需要知道具有相同名称副本的任何文件的位置和名称。
重复示例:
/www/images/taxi.jpg /www/images/Taxi.jpg
理想情况下,我需要从基本目录recursionsearch所有文件。 在上面的例子中,它是/www/
在linux命令行上按时间戳sorting日志文件
我可以在UNIX shell中执行嵌套或链接的命令吗?
从cmd.exeshellinput和输出
如何在windows命令行中逃避参数?
有没有办法使用在无头机器上使用硬件加速OpenGL的应用程序?
我可以在linux中为长控制台命令创build快捷方式吗?
如何解码.lzo_deflat文件?
如何使用grep来收集URL链接?
用于图像压缩的windows命令返回无效的参数错误
窗口wget&被切断
另一个答案是伟大的,但我建议,而不是“相当可怕的”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/2t1/L2,'|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"; } }
尝试:
ls -1 | tr '[AZ]' '[az]' | sort | uniq -c | grep -v " 1 "
简单,真的:-)不是管道奇妙的野兽?
ls -1给你每行一个文件, tr '[AZ]' '[az]'将所有大写字母转换成小写字母, sort它们(足够出乎意料的), uniq -c去掉后续出现的重复行,你也算一下,最后, grep -v " 1 "去掉count为1的行。
当我在一个“重复”(我复制qq到qQ )的目录中运行这个时,我得到:
2 qq
对于“这个目录和每个子目录”版本,只需用find .替换ls -1 find . 或者如果你想要一个特定的目录起始点( DIRname是你想要使用的目录名), find DIRname 。
这返回(对我来说):
2 ./.gconf/system/gstreamer/0.10/audio/profiles/mp3 2 ./.gconf/system/gstreamer/0.10/audio/profiles/mp3/%gconf.xml 2 ./.gnome2/accels/blackjack 2 ./qq
这是由于:
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
将被视为重复, 即使他们在不同的目录 。
如果你只想在单个目录中重复显示匹配,你可以使用(相当可怕的):
perl -ne ' chomp; @flds = split (///); $lstf = $f[-1]; $lstf =~ tr/AZ/az/; for ($i =0; $i ne $#flds; $i++) { print "$f[$i]/"; }; print "$xn";'
代替:
tr '[AZ]' '[az]'
它所做的只是小写路径名的最后部分,而不是整个事物。 另外,如果你只想要普通的文件(没有目录,FIFO等等),使用find -type f来限制返回的内容。
我相信
ls | sort -f | uniq -i -d
更简单,更快,并会给出相同的结果
这是一个很好的小命令行应用程序,如果你编译fslint ,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进行限定的限制性更大,因为只有名称不同的文件(或目录)才会被报告。 如果传输到不区分大小写的文件系统,IE -c将标记将冲突的文件和目录。 请注意,如果指定了-c或-C,并且没有指定指定当前目录的路径。
跟着mpez0的响应,递归检测只是用“find”来代替“ls”。 我看到的唯一的问题是,如果这是一个重复的目录,那么你有这个目录中的每个文件1条目。 一些人脑需要处理这个的输出。
但无论如何,你不会自动删除这些文件,是吗?
find . | sort -f | uniq -i -d
这里是一个例子如何找到所有重复的jar文件:
find . -type f -printf "%fn" -name "*.jar" | sort -f | uniq -i -d
将*.jar替换为您正在寻找的任何重复的文件类型。
这是一个为我工作的脚本(我不是作者)。 原文和讨论可以在这里找到: http : //www.daemonforums.org/showthread.PHP?t = 4661
#! /bin/sh # find duplicated files in directory tree # comparing by file name,SIZE or MD5 checksum # -------------------------------------------- # liCENSE(s): BSD / CDDL # -------------------------------------------- # vermaden [AT] interia [DOT] pl # http://strony.toya.net.pl/~vermaden/links.htm __usage() { echo "usage: $( basename ${0} ) OPTION DIRECTORY" echo " OPTIONS: -n check by name (fast)" echo " -s check by size (medium)" echo " -m check by md5 (slow)" echo " -N same as '-n' but with delete instructions printed" echo " -S same as '-s' but with delete instructions printed" echo " -M same as '-m' but with delete instructions printed" echo " EXAMPLE: $( basename ${0} ) -s /mnt" exit 1 } __prefix() { case $( ID -u ) in (0) PREFIX="rm -rf" ;; (*) case $( uname ) in (SunOS) PREFIX="pfexec rm -rf" ;; (*) PREFIX="sudo rm -rf" ;; esac ;; esac } __crossplatform() { case $( uname ) in (FreeBSD) MD5="md5 -r" STAT="stat -f %z" ;; (linux) MD5="md5sum" STAT="stat -c %s" ;; (SunOS) echo "INFO: supported systems: FreeBSD linux" echo echo "Porting to Solaris/OpenSolaris" echo " -- provIDe values for MD5/STAT in '$( basename ${0} ):__crossplatform()'" echo " -- use digest(1) instead for md5 sum calculation" echo " $ digest -a md5 file" echo " -- pfexec(1) is already used in '$( basename ${0} ):__prefix()'" echo exit 1 (*) echo "INFO: supported systems: FreeBSD linux" exit 1 ;; esac } __md5() { __crossplatform :> ${DUPliCATES_file} DATA=$( find "${1}" -type f -exec ${MD5} {} ';' | sort -n ) echo "${DATA}" | awk '{print $1}' | uniq -c | while read liNE do COUNT=$( echo ${liNE} | awk '{print $1}' ) [ ${COUNT} -eq 1 ] && continue SUM=$( echo ${liNE} | awk '{print $2}' ) echo "${DATA}" | grep ${SUM} >> ${DUPliCATES_file} done echo "${DATA}" | awk '{print $1}' | sort -n | uniq -c | while read liNE do COUNT=$( echo ${liNE} | awk '{print $1}' ) [ ${COUNT} -eq 1 ] && continue SUM=$( echo ${liNE} | awk '{print $2}' ) echo "count: ${COUNT} | md5: ${SUM}" grep ${SUM} ${DUPliCATES_file} | cut -d ' ' -f 2-10000 2> /dev/null | while read liNE do if [ -n "${PREFIX}" ] then echo " ${PREFIX} "${liNE}"" else echo " ${liNE}" fi done echo done rm -rf ${DUPliCATES_file} } __size() { __crossplatform find "${1}" -type f -exec ${STAT} {} ';' | sort -n | uniq -c | while read liNE do COUNT=$( echo ${liNE} | awk '{print $1}' ) [ ${COUNT} -eq 1 ] && continue SIZE=$( echo ${liNE} | awk '{print $2}' ) SIZE_KB=$( echo ${SIZE} / 1024 | bc ) echo "count: ${COUNT} | size: ${SIZE_KB}KB (${SIZE} bytes)" if [ -n "${PREFIX}" ] then find ${1} -type f -size ${SIZE}c -exec echo " ${PREFIX} "{}"" ';' else # find ${1} -type f -size ${SIZE}c -exec echo " {} " ';' -exec du -h " {}" ';' find ${1} -type f -size ${SIZE}c -exec echo " {} " ';' fi echo done } __file() { __crossplatform find "${1}" -type f | xargs -n 1 basename 2> /dev/null | tr '[AZ]' '[az]' | sort -n | uniq -c | sort -n -r | while read liNE do COUNT=$( echo ${liNE} | awk '{print $1}' ) [ ${COUNT} -eq 1 ] && break file=$( echo ${liNE} | cut -d ' ' -f 2-10000 2> /dev/null ) echo "count: ${COUNT} | file: ${file}" file=$( echo ${file} | sed -es/'['/'\['/g -es/']'/'\]'/g ) if [ -n "${PREFIX}" ] then find ${1} -iname "${file}" -exec echo " ${PREFIX} "{}"" ';' else find ${1} -iname "${file}" -exec echo " {}" ';' fi echo done } # main() [ ${#} -ne 2 ] && __usage [ ! -d "${2}" ] && __usage DUPliCATES_file="/tmp/$( basename ${0} )_DUPliCATES_file.tmp" case ${1} in (-n) __file "${2}" ;; (-m) __md5 "${2}" ;; (-s) __size "${2}" ;; (-N) __prefix; __file "${2}" ;; (-M) __prefix; __md5 "${2}" ;; (-S) __prefix; __size "${2}" ;; (*) __usage ;; esac
如果find命令不适合你,你可能不得不改变它。 例如
olD : find "${1}" -type f | xargs -n 1 basename NEW : find "${1}" -type f -printf "%fn"
您可以使用:
find -type f -exec readlink -m {} ; | gawk 'BEGIN{FS="/";OFS="/"}{$NF=tolower($NF);print}' | uniq -c
哪里:
find -type f
递归打印所有文件的完整路径。
-exec readlink -m {} ;
获取文件的绝对路径
gawk 'BEGIN{FS="/";OFS="/"}{$NF=tolower($NF);print}'
将全部文件名替换为小写
uniq -c
唯一的路径,-c输出重复的计数。
这一点晚了一点,但这是我跟随的版本:
find . -type f | awk -F/ '{print $NF}' | sort -f | uniq -i -d
我们在这里使用:
find – 找到当前目录下的所有文件
awk – 删除文件名的文件路径部分
sort – 不区分大小写
uniq – 从通过管道的东西中找到它们
(受@ mpez0答案启发,而@SimonDowdles评论@paxdiablo答案。)
您可以使用GNU awk检查给定目录中的重复项:
gawk 'BEGINfile {if ((seen[tolower(filename)]++)) print filename; nextfile}' *
在继续阅读文件之前,这使用BEGINfile来执行一些 *** 作。 在这种情况下,它跟踪出现在数组seen[] see seen[]中的名称,其索引是小写文件的名称。
如果一个名字已经出现了,不管它的情况如何,它都会打印出来。 否则,它只是跳转到下一个文件。
看一个例子:
$ 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
我只是在CentOS上使用fdupes来清理整个buncha重复文件…
yum install fdupes
总结以上是内存溢出为你收集整理的如何find重名的同名文件,但在不同情况下存在于同一目录中的Linux文件?全部内容,希望文章能够帮你解决如何find重名的同名文件,但在不同情况下存在于同一目录中的Linux文件?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)