我想选择文本文件的特定部分并将其打印/存储在另一个文件中。
选择在特定模式匹配时开始,在另一个模式匹配时结束。我必须在没有 awk 的情况下做到这一点。我正在尝试使用 sed。
- 找到后开始选择预期的
- 直到找到时为止实际的
> |e|build_event_details_json(e) })
expected collection contained: [{"id"=>18646, "state"=>"available", "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",actual collection contained: [{"id"=>18646
答案应该是
> expected collection contained: [{"id"=>18646, "state"=>"available", "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
答案1
不太优雅,也不太高效,但可以完成工作
sed 's/actual/\n&/' file | sed -n '/expected/,/actual/p' | sed '$d'
expected collection contained: [{"id"=>18646, "state"=>"available", "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
也许好一点(使用 GNU sed
):
sed -n '/expected/,$ {s/actual.*$//; p; T; q; } ' file
如果该T
命令不可用,请尝试
sed -n '/expected/,$ {s/actual.*$//; p; tL; b; :L; q; } ' file
答案2
仅使用 sed:
<infile sed 's/expected/\n&/;s/.*\n//;s/actual/\n&/;s/\nactual.*//'
解释:
s/expected/\n&/
在 之前放置一个换行符(分隔)expected
。s/.*\n//
删除上一个命令创建的引导线。s/actual/\n&/
在 之前放置一个换行符(分隔)actual
。s/\nactual.*//
删除上面创建的以 开头的行actual
。
actual
请注意,如果位于行的开头,上面将生成一个空行。如果需要避免空行,请使用:
<infile sed 's/expected/\n&/;s/.*\n//;/^actual/d;s/actual.*//'
另请注意,上述命令将保持与 或 不匹配的所有行保持不变expected
,actual
然后将被打印。
为了避免这种情况,请在前面添加/expected\|actual/!d
以下内容:
<infile sed '/expected\|actual/!d;s/expected/\n&/;s/.*\n//;/^actual/d;s/actual.*//'
如果需要的是范围expected
和之间的行actual
,但删除包含的尾随行,actual
然后使用:
<infile sed '/^expected/!{s/expected/\n&/};/^actual/!{s/actual.*/\n&/}' |
sed '/expected/,/actual/!d;/actual/d'
答案3
我认为应该这样做:
sed -n '/expected.*actual/{s/actual.*//;p;n};
/expected/,/actual/{s/actual.*//;p}' input
如果一行同时包含开始和结束标记,则丢弃结束标记之后的所有内容并读取下一行。否则,打印包含开始和结束标记的行之间的任何内容,再次丢弃结束标记之后的所有内容。
答案4
这看起来像是您正在尝试使用 sed 解析 JSON。这不是一个好主意。使用杰克如果可能的话。
尽管如此,您可以将整个文件放入内存中,并对其进行搜索和替换:
$ cat file
foo
bar
> |e|build_event_details_json(e) })
expected collection contained: [
{"id"=>18646,
"state"=>"available",
"salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
actual collection contained: [
{"id"=>18646
baz
qux
$ sed -n 'H;${g;s/.*\(expected.*\)actual.*/\1/p}' file
expected collection contained: [
{"id"=>18646,
"state"=>"available",
"salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
请注意,这将从最后的“期望”到最后的*
由于量词的贪婪而遵循“实际”
$ cat file
foo
expect1
bar
> |e|build_event_details_json(e) })
expected collection contained: [
{"id"=>18646,
"state"=>"available",
"salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
actual collection contained: [
{"id"=>18646
baz
actual2
qux
$ sed -n 'H;${g;s/.*\(expected.*\)actual.*/\1/p}' file
expected collection contained: [
{"id"=>18646,
"state"=>"available",
"salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
actual collection contained: [
{"id"=>18646
baz