我有下一个问题:
目录Example1
包含三个文件:Example1
、Things
和Pictures
。
目录Example2
包含三个文件:Example2
、Example3
和Pictures
。
我需要一个仅显示与目录名称匹配的文件的列表,这是:Example1
和Example2
。我尝试过 diff、find、locate 和 ls...但我没有取得任何成果。
答案1
您可以使用反向引用轻松地将与包含目录同名的文件名与正则表达式匹配。这些是what/ever/something/something
两个something
部分相同且不包含斜杠的形式的文件名。在 BRE 正则表达式语法中,[^/]*
匹配任何不包含斜杠的字符串,\(/[^/]*\)
匹配斜杠后跟任意数量的非斜杠字符并使整个事物成为一个组,并\1
匹配与第一个组匹配的相同文本,因此\(/[^/]*\)\1
匹配两个具有相同名称的路径段。.*
在开头添加以匹配先前的目录组件。
使用 GNU find、FreeBSD find、macOS find 或任何其他find
支持的-regex
:
find . -regex '.*\(/[^/]*\)\1'
答案2
由于目录通常比文件少,因此我们查找所有目录,然后测试它们是否包含所需的文件名。
find . -type d -exec sh -c '
for dirpath do
filepath="$dirpath/${dirpath##*/}"
[ -f "$filepath" ] && printf "%s\n" "$filepath"
done' sh {} +
这将打印位于与该文件同名的目录中的所有常规文件(以及常规文件的符号链接)的路径名。
该测试是在一个简短的内联sh -c
脚本中完成的,该脚本将获取许多目录路径名作为参数。它迭代每个目录路径名并使用我们正在查找的名称构造一个文件路径名。${dirpath##*/}
代码中的 可以替换为$(basename "$dirpath")
.
对于给定的示例目录结构,这将输出
./Example1/Example1
./Example2/Example2
只是测试任何名字,不只是常规文件,把-f
测试改成-e
测试。
答案3
使用find -exec
:
find . -type f \
-exec sh -c '[ "$(basename "$1")" = "$(basename "$(dirname "$1")")" ]' find-sh {} \; \
-print
仅当内部-print
结果为 true 时才会执行。[ ... ]
-exec sh -c '...'
输出:
./Example1/Example1
./Example2/Example2