我有一个给定的文件:
application_1.pp
application_2.pp
#application_2_version => '1.0.0.1-r1',
application_2_version => '1.0.0.2-r3',
application_3.pp
#application_3_version => '2.0.0.1-r4',
application_3_version => '2.0.0.2-r7',
application_4.pp
application_5.pp
#application_5_version => '3.0.0.1-r8',
application_5_version => '3.0.0.2-r9',
我希望能够读取此文件并搜索字符串
".pp"
找到该字符串后,它会将该行添加到变量中并存储它。 然后它读取文件的下一行。如果它遇到以#开头的行,则忽略它并移动到下一行。
如果遇到不包含" .pp"并且不以#开头,它应该打印出新文件中最后一个存储变量旁边的那条线。
输出如下:
application_1.pp
application_2.pp application_2_version => '1.0.0.2-r3',
application_3.pp application_3_version => '2.0.0.2-r7',
application_4.pp
application_5.pp application_5_version => '3.0.0.2-r9',
我想用awk实现这个目标。如果有人知道如何做到这一点,这是一个简单的解决方案,如果他们能与我分享,我会很高兴。如果它更复杂,那么知道我需要理解什么才能知道如何做到这一点(数组,变量等)会很有帮助。甚至可以用awk实现它还是另一种必要的工具?
谢谢,
答案 0 :(得分:1)
我会说
awk '/\.pp/ { if(NR != 1) print line; line = $0; next } NF != 0 && substr($1, 1, 1) != "#" { line = line $0 } END { print line }' filename
其工作原理如下:
/\.pp/ { # if a line contains ".pp"
if(NR != 1) { # unless we just started
print line # print the last assembled line
}
line = $0 # and remember this new one
next # and we're done here.
}
NF != 0 && substr($1, 1, 1) != "#" { # otherwise, unless the line is empty
# or a comment
line = line $0 # append it to the line we're building
}
END { # in the end,
print line # print the last line.
}
答案 1 :(得分:1)
您可以使用sed:
#n
/\.pp/{
h
:loop
n
/[^#]application.*version/{
H
g
s/\n[[:space:]]*/\t/
p
b
}
/\.pp/{
x
p
}
b loop
}
如果您将其保存为s.sed并运行
sed -f s.sed file
您将获得此输出
application_1.pp
application_2.pp application_2_version => '1.0.0.2-r3',
application_3.pp application_3_version => '2.0.0.2-r7',
application_4.pp
application_5.pp application_5_version => '3.0.0.2-r9',
<强>解释强>
#n
取消正常输出。
匹配/\.pp/
后,我们会使用h
将该行存储到保留空间,然后启动loop
。
我们使用n
如果它与/[^#]application.*version/
匹配,意味着它不以#
开头,那么我们会使用H
将该行附加到保留空间,然后将保留空间复制到带有g
的模式空间,并用换行符和任何后续空格替换选项卡。最后,我们使用p
打印,然后使用b
如果匹配/\.pp/
,则我们交换模式并使用x
保留空格,然后使用p
进行打印。