0

我想在一些名称块的顶部解析一个带有名称和注释的文件。如果我有这样的文件:

Art
Boat
Road
Tree
Street

# Blah
Star
Car
Sun

Sock

# Comm1
# Comm2
Stop
Stick
# Comm
Stock
Dock

我想以某种方式解析这个文件,以便提取所有以“S”开头的名称及其相应的注释。对应的注释是紧接在前面的注释块(一行或多行注释),直到在它前面遇到一个空格。一个注释块也适用于它后面的所有条目,直到遇到空格或另一个注释块。所以上述输入的输出应该是这样的:

**Name      Comments**

Street
Star        # Blah
Sun         # Blah
Sock
Stop        # Comm1 # Comm2
Stick       # Comm1 # Comm2
Stock       # Comm

任何人都可以提出一个很好的方法来做到这一点(最好使用shell)?真的很感激。谢谢!

PS:如果我的描述不清楚,我很抱歉,这还是新的。

4

2 回答 2

1

这是一些有点不雅的 awk 可以完成这项工作:

awk '/^$/ {ca=""; cp=""} /^#/ {ca=ca " " $0} /^S/ && ca {cp=ca; ca=""} /^S/ {print $0 " " cp}' < input.txt > output.txt

有两个存储:注释累加器ca和注释打印缓冲区cp

  1. 每当遇到空行时,两者都被清除。
  2. 当遇到注释行时,它被添加到注释累加器中。
  3. 当遇到以 S 开头的行并且注释累加器有内容时,注释打印缓冲区被设置为注释累加器中的任何内容,并且后者被清除。
  4. 当遇到以 S 开头的行时,将打印它,然后是注释打印缓冲区中的任何内容。

可能有一种更优雅的方法可以做到这一点,这无疑有问题(例如,在行尾放置一个空格而没有评论),但它会让你开始。

于 2012-08-01T01:01:51.157 回答
1

假设您的空白行不包含空格:

sed -n '/^#/H; /^S/{G; y/\n/ /; p}; /^$/h' input

第一个命令 ( /^#/H) 将当前行(注释)附加到保留空间。下一个命令将保留空间(包含所有累积的注释)附加到当前缓冲区,用一个空格替换所有换行符,然后打印该行。每当遇到空行时,最后一个命令都会清除保留空间。

编辑(感谢blahdiblah)

当检测到没有前面空行的新注释块时,上述内容不会正确重置累加器。这很丑陋,但说明了这一点:

sed -n '/^#/{h; bk}; :j /^S/{G; y/\n/ /; p}; /^$/h; d; :k n; /^#/{ H; bk}; bj;' input
于 2012-08-01T22:38:35.700 回答