使用 sed / bash 脚本删除最后一次出现的变量

使用 sed / bash 脚本删除最后一次出现的变量

我有多个文件写为 */*/*/*/ ... */*.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,而不仅仅是常规文件。


zshshell 中:

typeset -U dirs=(./**/*.(h|hpp)(.ND:h))
print -r -C1 $dirs

这将创建一个数组变量 ,dirs它仅存储唯一元素。我们将其初始化为当前目录下任意位置的目录集,其中包含与*.h或匹配的常规文件*.hpp,然后打印数组的内容。

相关内容