我有一个目录很少的项目(事先并不知道所有目录)。我想发出一个命令来查找包含源的所有目录。像find . -name "*.cpp"
这样的东西会给我一个源列表,而我只想要一个包含它们的目录列表。项目结构事先不知道,目录X中可能存在某些源,而子目录X / Y中可能存在其他源。将打印包含源的所有目录列表的命令是什么?
答案 0 :(得分:5)
find . -name "*.cpp" -exec dirname {} \; | sort -u
如果(a)您有GNU find
或最新版本的BSD find
和(b)您有最新版本的dirname
(例如GNU coreutils 8.21或FreeBSD 10)但不 OSX 10.10),那么,为了提高效率,请使用(帽子提示:Jochen和mklement0):
find . -name "*.cpp" -exec dirname {} + | sort -u
答案 1 :(得分:3)
John1024's answer 优雅且快速,如果您的dirname
版本支持多个参数< / strong>,您可以使用-exec dirname {} +
调用它。
否则,对于-exec dirname {} \;
,子进程会为每个输入文件名分叉,这很慢。
如果:
dirname
不支持多个参数4
或更高版本考虑以下解决方案:
shopt -s globstar; printf '%s\n' ./**/*.cpp | sed 's|/[^/]*$||' | sort -u
shopt -s globstar
激活对跨目录路径名扩展(globbing)的支持 ./**/**.cpp
然后匹配当前目录的子树
.cpp
个文件
./
开头,因此下面的sed
命令也会正确报告顶级目录本身,如果它包含匹配的文件。< / LI>
sed 's|/[^/]*$||'
有效地执行与dirname
相同的操作,但在所有输入行上执行单调用{{1} }}
sed
对结果进行排序,并仅输出唯一的目录名称。答案 2 :(得分:1)
find . -name "*.cpp" | while read f; do dirname "$f" ; done | sort -u
应该做你需要的事情
答案 3 :(得分:1)
find . -name '*.cpp' | sed -e 's/\/[^/]*$//' | sort | uniq
答案 4 :(得分:1)
简单地找到非空目录:
$ find . \! -empty -type d
对于只包含特定文件类型的目录,我会使用以下内容:
find . -name \*.cpp | while read line; do dirname "${line}" ; done | sort -u
这会查找所有* .cpp文件,并在每个文件名上调用dirname
。然后对结果进行排序并使其唯一。使用不需要为每个* .cpp文件生成新进程的shell-builtins,确实有更快的方法。但这对大多数项目来说可能并不重要。
答案 5 :(得分:0)
您应该定义什么是源文件。
请注意某些C或C ++文件生成 (例如,通过bison或yacc
等解析器生成器,通过ad-hoc { {1}}或awk
或shell脚本,特定于项目的生成器等等,以及一些包含C或C ++文件的文件未命名为python
或.h
(阅读X-macros)。在GCC内生成大量文件(例如,来自.cc
机器描述文件,这些文件是可靠的源文件)
大多数大型软件项目(例如数百万行C ++或C代码)已经或正在某处使用某些C或C ++代码生成器。
在自由软件世界中,源代码只是开发人员正在使用的代码的首选表单。
请注意,源代码甚至可能不在文件中;它可以放在数据库中,在某些堆映像中,例如如果开发人员正在与特定程序交互工作。 (记住20世纪80年代的Smalltalk机器,或1980年INRIA的Mentor structured editor)。另一个例子是,J.Pitrat的CAIA系统的C代码完全由自己生成。另请参阅Scheme48
也许(仅作为近似启发式)您应该将任何名为*.md
或.h
或.cc
或.cpp
或{{1}的文件视为C ++源文件}}或.cxx
或.def
,其中不包含.inc
个字词(通常在某些评论中)。
要了解生成的文件是什么,您应该深入了解构建过程(由.tcc
,GENERATED FILE
,Makefile
和CMake*
等描述......)。 检测或猜测生成的 C ++ 文件没有万无一失的方法;所以你将无法可靠地自动检测。
最后,引导语言通常有一个(版本控制)存储库,其中包含一些生成的文件。 Ocaml有一个boot/
subdirectory,MELT有一个Makefile.am
目录(包含从autoconf
源代码文件中以C ++形式重新生成MELT所需的C ++文件。)
我建议使用项目版本控制repository并获取非空目录。详细信息取决于version control工具(例如git,melt/generated/
或*.melt
等...)。您应使用某些版本控制(或版本控制)工具。我推荐svn