查找所有同名文件

查找所有同名文件

我在不同的文件夹中有很多同名的文件。如何找到所有路径并将它们写入文本文件?

答案1

这将处理您知道存在重复文件名但不知道它们是什么的一般情况:

find -type f -print0 |
    awk -F/ 'BEGIN { RS="\0" } { n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'

awk脚本中,我们处理以 NULL 结尾的文件路径(因此我们可以处理可能包含换行符的文件名),并将其$0作为当前文件路径名。该变量n保存文件名部分。k[]是一个散列(以 为键n),用于计算此文件名出现的次数,并且p[]是另一个散列(也以 为键n),用于保存第一个相应的完整路径名。

例子

# Preparation
mkdir -p tmp/a tmp/b
touch tmp/a/xx tmp/a/yy tmp/b/yy tmp/b/zz

# Do it
find tmp -type f -print0 |
    awk -F/ 'BEGIN { RS="\0" } { n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'

tmp/a/yy
tmp/b/yy

# Tidyup
rm -rf tmp

如果您使用 POSIX find(例如,如果您使用的是 Mac),那么您将没有该-print0选项,因此解决方案和命令略有不同。您需要指定一个明确的起始目录。此外,此版本find将无法处理以 NULL 结尾的文件名,因此它仅适用于不包含换行符的文件名:

find . -type f -print |
    awk -F/ '{ n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'

答案2

我会用find.就像这样:

find <path> -type f -name <filename> > same_name.txt

例子:

find . -type f -name "foo" > same_name.txt
cat same_name.txt 
./dir_a/foo
./foo
./dir_b/foo
./tmp/foo

上面的代码从当前目录开始递归查找所有名为 的文件foo。结果保存在文件中same_name.txt

答案3

如果已安装,则可以使用locate.

locate filename

或保存到文件:

locate filename > same_name.txt

要仅搜索某个位置,您可以使用 grep 过滤结果:

locate filename | grep "/path/"
# e.g. search only in your /home folder
locate filename | grep "$HOME"

笔记:

  • locate很多比 更快find,因为它每天一次扫描您的硬盘来执行数据库搜索。
  • 它不会找到您今天添加的文件。
  • 它不会在某些路径或文件系统和安装中查找文件(运行cat /etc/updatedb.conf以查看排除的内容。)

答案4

以下bash脚本递归地查找在脚本命令行上给定的顶级路径中(如果未给出路径,则在当前目录中)重复的常规文件(或常规文件的符号链接)的所有名称。

最后,给出每个重复文件名的摘要,以及:可以找到该文件名的目录名的 - 分隔列表。

#!/bin/bash

shopt -s globstar  # enable the ** glob
shopt -s dotglob   # also let patterns match hidden files

declare -A dirs    # where we store directories for each found name

for pathname in "${1:-.}"/**; do
    [ ! -f "$pathname" ] && continue  # not something we're interested in

    name=${pathname##*/}
    if [ -n "${dirs[$name]}" ]; then
        # we have seen this filename before
        dups+=( "$name" )
    fi

    # append directory name to ':'-delimited list for this filename
    dirs[$name]=${dirs[$name]:+"${dirs[$name]}:"}"${pathname%/*}"
done

# go through the list of duplicates and 
# print the found directory names for each
for name in "${dups[@]}"; do
    printf '%s:\n\t%s\n' "$name" "${dirs[$name]}"
done

运行示例:

$ bash script.sh
somefile:
        ./a:./b
.profile:
        .:./t

摘要告诉我们,.profile在当前目录以及目录中找到t,以及somefile在目录a和中找到b

相关内容