我正在从事大量涉及 Fortran 代码的项目。它们位于包含 10 到 20 个文件夹的目录树中,每个代码都位于“src”文件夹中。
我正在寻找的是简单的我可以在树状结构的根部运行该命令来获取有关程序的所有相关信息。此信息在 .f 或 .f90 文件的头部进行注释,但当然它可以在每个文件中的不同行数上运行。
一个困难是它并不总是位于文件的最开头,因为有时首先是模块。但这些信息总是让人想起文件的名称,或者至少包含“main”一词。
更准确地说,树状结构如下:
/
|-folder1/
|-program1.f
|-folder2/
|-program2.f90
我program1.f
需要以下块:
c
c program1 does the following
c blah blah
c
(这可能是大写的C)
我program2.f90
需要以下内容:
!
! program2 does the following
! blah blah
!
或许,有一个正则表达式哪个可以用来获取完整的通知块?
答案1
你可以尝试一下这个命令。它可能需要针对您想要的评论(与您不想要的评论)的特定布局进行调整。
find . -type f -regex ".*\.[fF]\(90\)?" -exec awk '/^[Cc!]\ *program/{f=1} f{if(/^[^Cc!]/) exit; print}' {} \;
这将在目录树中找到所有常用的 Fortran 文件,并打印以! program
, C program
or开头的第一个注释块c program
,并仅打印该注释块的全部内容。我根据您的示例评论块选择了这些正则表达式。
如果您需要对此进行调整,请在评论中告诉我,或者我们可以设置一个聊天室来解决这个问题。这应该能让你开始做你想要的事情。如果您的评论并不总是以program
in 开头,您可以尝试
find . -type f -regex ".*\.[fF]\(90\)?" -exec awk '/^[Cc!]\ *$/{f=1} f{if(/^[^Cc!]/) exit; print}' {} \;
它将在第一行开始匹配,仅使用注释字符和可选的空格。
笔记这些匹配依赖于第 1 列中的注释字符。如果您有自由格式文件,其中的注释块需要在不同的列中开始(对于顶级注释而言并不常见),那么这些匹配将不起作用。
这是如何运作的:
find . -type f -regex ".*\.[fF]\(90\)?"
从当前目录(更改.
为绝对路径以便能够在任何地方运行)递归搜索任何名为*.f
、*.F
、*.f90
或 的文件*.F90
。然后它执行:
awk '/^[Cc!]\ *program/{f=1} f{if(/^[^Cc!]/) exit; print}' {} \;
在它找到的每个文件上。让我们分解一下:
/^[Cc!]\ *program/{f=1}
这匹配以注释字符开头的第一行C
,c
或者!
包含任意数量的空格,然后包含单词program
。这与示例注释块的第一实际行相匹配。 awk 打印这一行并继续打印行直到
if(/^[^Cc!]/) exit;
已匹配。这匹配不以注释字符开头的第一行。此时 awk 退出并处理下一个文件。
答案2
如果您需要的信息位于独立的行上,那么递归grep
就是正确的选择。例如,如果您想查找所有注释行,类似的操作grep -r ^C
可能会成功。 (我猜测这里的注释语法。我是老派,但不是那老套)。
如果您需要更复杂的逻辑,例如“获取以 BLAH 开头的第一个行块中的所有行,但在第一个非 BLAH 行之后停止”,那么您必须依次在每个文件上调用命令,可能是sed
或awk
。为此,find
你的朋友:通常你会做类似的事情
find -exec awk '<AWK expression extracting what you need>' {} \;