Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sed 如何从用新行分隔的多个文本块中提取第一行和最后一行?_Sed - Fatal编程技术网

Sed 如何从用新行分隔的多个文本块中提取第一行和最后一行?

Sed 如何从用新行分隔的多个文本块中提取第一行和最后一行?,sed,Sed,我有一个包含多个测试的文件,详细的操作一个接一个地写。所有试块通过新线彼此分离。我只想从所有块中提取第一行和最后一行,并将每个块的第一行和最后一行放到一个新文件中。以下是一个例子: input.txt: [test1] duration summary code= Results= PASS [test2] duration summary=x code= Results=FAIL ..... [testX] duration summary=x code= Results= PASS

我有一个包含多个测试的文件,详细的操作一个接一个地写。所有试块通过新线彼此分离。我只想从所有块中提取第一行和最后一行,并将每个块的第一行和最后一行放到一个新文件中。以下是一个例子:

input.txt

[test1]
duration
summary
code=
Results= PASS

[test2]
duration
summary=x
code=
Results=FAIL

.....

[testX]
duration
summary=x
code=
Results= PASS
output.txt有时应该是这样的:

test1 PASS
test2 FAIL
...
testX PASS
eg2:


谢谢大家!

解决此问题的一种方法是使用正则表达式,例如:

(?<testId>test\d+)(?:.*\n){4}.*(?<outcome>PASS|FAIL)
生成包含以下内容的文件
output.txt

[test1]
duration
summary
code=
Results= PASS

[test2]
duration
summary=x
code=
Results=FAIL

[test444]
duration
summary=x
code=
Results= PASS
test1 PASS
test2 FAIL
test444 PASS

使用标记的
sed
(尽管使用其他工具可能更自然):

说明:

/^\[.*\]$/h         # matches the [...] lines, put them in the hold buffer
s/^Results= ?//     # matches the Results= lines, discards the useless part
t r;b               # on lines which matched, jump to label r; 
                    # otherwise jump to the end (and start processing the next line)
:r;H;x;s/\n/ /;p    # label r; append the pattern space (which contains the end of the Results= line)
                    # to the hold buffer. Switch Hold buffer and pattern space,
                    # replace the linefeed in the pattern space by a space and print it

您可以。

要打印块中的第一行和最后一行,请执行以下操作:

awk -v RS="" '{
    n = split($0, a, /\n/)
    print a[1]
    print a[n]
}' input.txt
第一个示例的结果:

[Linux_MP3Enc_xffv.2_Con_37_003]
Total_Result = PASS
[Composer__vtx_007]
Total_Result = PASS
[Videox_Rotate_008]
Total_Result = PASS
awk
的手册页显示:

如果RS设置为空字符串,则记录之间用空行分隔

使用此功能可以轻松地用空行分割块


希望这有帮助。

简短的
gnu awk

awk -F= -v RS='' '{print $1 $NF}' file
[Linux_MP3Enc_xffv.2_Con_37_003] PASS
[Composer__vtx_007] PASS
[Videox_Rotate_008] PASS
如果您不喜欢括号:

awk -F'[]=[]' -v RS='' '{print $2 $NF}' file
Linux_MP3Enc_xffv.2_Con_37_003 PASS
Composer__vtx_007 PASS
Videox_Rotate_008 PASS

非常感谢。对于这个特定的例子,这是一个非常好的实现,但是我忘了提到测试名称从一个块更改到另一个块,以及块的行数,这就是为什么我询问块中的第一行和最后一行。它是有效的。非常感谢你!我是一个新用户,所以不能给你+1,因为我的声誉不足15。PS:所有的解决方案都很棒。谢谢你们!(+对大家)谢谢你们的时间和解释!(+)谢谢你的时间和解释!(+1). 这很有帮助。
awk -F= -v RS='' '{print $1 $NF}' file
[Linux_MP3Enc_xffv.2_Con_37_003] PASS
[Composer__vtx_007] PASS
[Videox_Rotate_008] PASS
awk -F'[]=[]' -v RS='' '{print $2 $NF}' file
Linux_MP3Enc_xffv.2_Con_37_003 PASS
Composer__vtx_007 PASS
Videox_Rotate_008 PASS