我有多个文件写为 */*/*/*/ ... */*.h 或 .hpp。我需要获取这些文件的目录,而不是文件本身。有没有什么办法,使用 sed,我可以做类似“查找最后一个 / 行,然后删除接下来直到 \n 的任何内容?”
PS:我知道 \(.*\) 或 (.*) ,然后将第 i 个出现称为 \i,但是有没有办法告诉 sed 删除 \i?\
编辑:
我通过执行类似的操作生成了一个文件
find . | grep *.h >> file ; find . | grep *.hpp >> file
我想要处理的是这个文件的内容。
答案1
要获取包含带有文件名后缀的文件的目录.h
或.hpp
使用find
:
find . -type f \( -name '*.h' -o -name '*.hpp' \) -exec dirname {} \;
这会查找名称与两个给定模式之一匹配的所有常规文件的路径名。对于每个这样的路径名,该dirname
实用程序用于提取路径名的目录路径部分。
使用 GNU find
,你可以这样做
find . -type f \( -name '*.h' -o -name '*.hpp' \) -printf '%h\n'
这使用非标准的格式选项-printf
来打印路径名的“头部”(即目录路径)%h
。
要获取唯一的路径名,您可以切换为查找目录而不是文件:
find . -type d -exec bash -O nullglob -O dotglob -c '
for pathname do
set -- "$pathname"/*.{h,hpp}
[[ $# -ne 0 ]] && printf "%s\n" "$pathname"
done' bash {} +
这bash
会为目录的批量路径名运行一个简短的脚本。简短的脚本在启用nullglob
和shell 选项的情况下运行dotglob
,这意味着不匹配任何内容的通配模式将被删除,并且通配模式也可能与隐藏名称匹配。
该循环迭代当前批次的路径名,并在每个目录中扩展两个通配模式*.h
和。*.hpp
如果模式至少匹配一个名称,则输出目录的路径名。
然而,最后一个变体将报告包含与名称*.h
或匹配的任何类型的文件的目录*.hpp
,而不仅仅是常规文件。
在zsh
shell 中:
typeset -U dirs=(./**/*.(h|hpp)(.ND:h))
print -r -C1 $dirs
这将创建一个数组变量 ,dirs
它仅存储唯一元素。我们将其初始化为当前目录下任意位置的目录集,其中包含与*.h
或匹配的常规文件*.hpp
,然后打印数组的内容。