在 Unix 中使用 sed 选择文本

在 Unix 中使用 sed 选择文本

我想选择文本文件的特定部分并将其打印/存储在另一个文件中。

选择在特定模式匹配时开始,在另一个模式匹配时结束。我必须在没有 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.*//'

另请注意,上述命令将保持与 或 不匹配的所有行保持不变expectedactual然后将被打印。
为了避免这种情况,请在前面添加/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

相关内容