如何使用sed/awk/grep在单独的文件中打印两个相同单词之间的行?
我想打印两个图案之间的所有线条,每个部分都在一个单独的文件中 模式:如何使用sed/awk/grep在单独的文件中打印两个相同单词之间的行?,awk,sed,grep,Awk,Sed,Grep,我想打印两个图案之间的所有线条,每个部分都在一个单独的文件中 模式: ATOM 10185 O WAT 622 86.629 114.783 125.073 1.00 0.00. ATOM 10186 H1 WAT 622 87.265 114.479 125.721 1.00 0.00. ATOM 10187 H2 WAT 622 86.215 115.543 125.482 1.00 0.00. TER
ATOM 10185 O WAT 622 86.629 114.783 125.073 1.00 0.00.
ATOM 10186 H1 WAT 622 87.265 114.479 125.721 1.00 0.00.
ATOM 10187 H2 WAT 622 86.215 115.543 125.482 1.00 0.00.
TER
ATOM 10188 O WAT 623 84.441 115.565 126.663 1.00 0.00.
ATOM 10189 H1 WAT 623 85.076 115.261 127.311 1.00 0.00.
ATOM 10190 H2 WAT 623 84.027 116.325 127.071 1.00 0.00.
TER
ATOM 10191 O WAT 624 85.591 117.441 124.690 1.00 0.00.
ATOM 10192 H1 WAT 624 86.226 117.137 125.338 1.00 0.00.
ATOM 10193 H2 WAT 624 85.176 118.201 125.098 1.00 0.00.
TER
我希望在新文件中包含以下内容:
文件1:
ATOM 10185 O WAT 622 86.629 114.783 125.073 1.00 0.00.
ATOM 10186 H1 WAT 622 87.265 114.479 125.721 1.00 0.00.
ATOM 10187 H2 WAT 622 86.215 115.543 125.482 1.00 0.00.
TER
文件2:
ATOM 10188 O WAT 623 84.441 115.565 126.663 1.00 0.00.
ATOM 10189 H1 WAT 623 85.076 115.261 127.311 1.00 0.00.
ATOM 10190 H2 WAT 623 84.027 116.325 127.071 1.00 0.00.
TER
等等
我尝试了在网站和互联网上找到的所有东西,但最终没有得到我所需要的。主要是如何在两种模式(如patern1xxxxxpatern2)之间进行grep,然后将它们打印到文件中。(、及类似)
我尝试了这一点,但在源代码第1行出现了错误awk:invalize语句:
awk '/TER/{n+=1}{print > "file_"n".txt"}'
感谢类似BSD系统上的man(1)awk给出了以下答案:
/start/, /stop/
Print all lines between start/stop pairs.
% cat 1.txt
l-2
l-1
TER1
l1
l2
l3
l4
l5
TER2
l6
l7
测试:
类似BSD系统上的man(1)awk给出了以下答案:
/start/, /stop/
Print all lines between start/stop pairs.
% cat 1.txt
l-2
l-1
TER1
l1
l2
l3
l4
l5
TER2
l6
l7
测试:
警告:
我尝试了这个,但是我得到了错误“awk:unligal statement at”
来源第1行“:
awk'/TER/{n+=1}{print>“file_u“n”.txt”}
这可能是由于输出重定向右侧的unpenthesised表达式导致的,因为根据POSIX,这是未定义的行为。如果是这样的话,那么将“file_“n.txt”
更改为(“file_“n.txt”)
将使您克服这个问题,继续解决下一个问题。以下是如何使用任何awk实现您想要的功能:
awk '
BEGIN { out = "file" (++c) }
{ print > out }
$0=="TER" {
close(out)
out = "file" (++c)
}
' file
警告:
我尝试了这个,但是我得到了错误“awk:unligal statement at”
来源第1行“:
awk'/TER/{n+=1}{print>“file_u“n”.txt”}
这可能是由于输出重定向右侧的unpenthesised表达式导致的,因为根据POSIX,这是未定义的行为。如果是这样的话,那么将“file_“n.txt”
更改为(“file_“n.txt”)
将使您克服这个问题,继续解决下一个问题。以下是如何使用任何awk实现您想要的功能:
awk '
BEGIN { out = "file" (++c) }
{ print > out }
$0=="TER" {
close(out)
out = "file" (++c)
}
' file
这可能适合您(GNU csplit):
这将创建文件file0
到filen
,每个文件都包含模式TER
,作为每个文件的最后一行。这可能适合您(GNU csplit):
这将创建文件file0
到filen
每个文件都包含模式TER
,作为每个文件的最后一行。您能写出整个表达式吗?我必须说,我没有经常使用awk。我使用了与sed-n'/TER/,/TER/p'file1>file2类似的东西,但我希望每个部分都在一个单独的输出文件中。我有非常大的文件,所以,因为在每个段之后我都有“TER”而不是“TER1”,“TER2”这不起作用。如果在pattern1和pattern2中都使用TER,则输出文件中只打印单词TER。切勿使用范围表达式(/start/,/stop/
)因为它们使琐碎的任务比其他方法写起来稍微简单一些,但是需要完全重写和/或复制条件来完成任何更有趣的事情。你能写出整个表达式吗?我必须说,我没有经常使用awk。我使用了与sed-n'/TER/,/TER/p'file1>file2类似的东西,但我希望每个部分都在一个单独的输出文件中。我有非常大的文件。所以,因为在每个片段之后,我有“TER”而不是“TER1”,“TER2”,这不起作用。如果我在pattern1和pattern2中都使用TER,那么输出文件中只会打印TER一词。永远不要使用范围表达式(/start/,/stop/
),因为它们使琐碎的任务比其他方法编写起来稍微简单一些,但随后需要完全重写和/或复制条件,即使是最细微的内容。谢谢Ed,我尝试了你的代码(我必须说我不完全理解所有命令的含义,比如++c),但我得到的是一个包含所有段的输出文件。如何将两个TER之间的每个段放在单独的文件中?然而,也许我做错了什么。我不是真的精通awk。再一次-根据你在问题中提供的例子,你不是试图得到每个片段在2个TER之间,而是试图得到每个片段以TER结尾。如果我发布的脚本不完全符合您的要求,那么您的实际数据与您提供的示例不一样。您可能有DOS行结尾,因此请尝试在您的文件上运行dos2unix
或类似程序。或者,您可以将$0==“TER”
更改为/TER/
。我更新了问题中数据的外观。事实上,这可能是因为我没有正确地表达自己。我发布的解决方案适用于任何以TER结尾的数据,包括您的原始数据和新数据。。写下++c
的意思-在您自己编写的n+=1
代码中,您可以在该上下文中编写++n
或n++
。它只是增加变量n
,或者在我的例子中是c
(用于“计数”)。我为您格式化了输入、输出和代码,这样您就可以在下一个问题中使用该示例。有关更多格式信息,请参阅。如果我发布的脚本不符合您的要求,请务必告诉我,因为它正是您发布的数据所需的解决方案。因此,如果它不适合您,则可能是您复制/粘贴了错误的脚本,或者您的真实数据与示例数据不符(可能只是跟在前面提到的`r
s后面)。谢谢Ed,我尝试了你的代码(我必须说我不完全理解所有命令的含义,比如++c),但我得到的是一个包含所有段的输出文件。我如何将两个TER之间的每个段放在单独的文件中?但是,也许我做错了什么。我对awk不是很精通。同样,根据您在问题中提供的示例,您并不是试图将每个段放在两个TER之间,而是试图将每个段放在两个TER之间以TER结尾。如果我发布的脚本不完全符合您的要求,那么您的实际数据看起来与您提供的示例不一样。您可能有DOS行结尾,因此请尝试在文件上运行dos2unix
或类似程序。或者,您可以更改$0==“TER”
到/TER/
。我更新了问题中数据的外观。可能是我没有更新