我在不同的文件夹中有很多同名的文件。如何找到所有路径并将它们写入文本文件?
答案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
。