grep 文本文件中的多行

grep 文本文件中的多行

有谁知道如何从文本文件中 grep 多行?我用谷歌搜索了很多结果,但仍然没有完全发挥作用。

文本文件示例:

x
x
x
---
start
a
b
c
d
---
x
x
x

我只想从文件中获取这个:

---
start
a
b
c
d
---

它可以更短 (ab) 或更长 (abcdefg),但始终以以下内容开头:

---
start

并以以下内容结尾:

---

多谢

答案1

您可以使用以下-z选项grep

-z, --null-data 数据行以 0 字节结束,而不是换行符

$ grep -zo -- '---.start[^-]*---' file
---
start
a
b
c
d
---

答案2

如果您确定在文本中(如示例所示)不存在行后面---始终跟着 的“技巧”部分start,则可以将节标题减少为---,并使用 :

sed -n '/---/,//p' text

如果您对上述说法不确定:

sed -n '/---/{n;/start/{:a H;n;/---/!ba;x;G;s/^/---/p;s/.*/\n---/;D}}' test


sed : /bin/sed executable
-n : sed option to avoid auto line printing
/---/ : Match a pattern of 3 "-"
n: Get the next line of input
/start/: Match a line "start"
:a : Build a label called "a" (For the loop)
H: Happend the line to the HOLD space (Save it)
n: Get the next line
/---/!: Test if the current line **is not** equal to: "---"
ba: Jump to the label 'a' if the test succede
x: Swap the Hold space and the Pattern space.
G: Get the line from the Hold space and append it to the Pattern space
s/^/---/p: Append to the start of the string a sequence of "---" and print the line
s/.*/\n---/: Replace the current line with a new line and an : "---"
D: Delete character in the current line (Pattern space) up to the  first new line character and start the next cycle with the remaining line

awk在段落模式下:

awk -v h="---" -v h2="start" '                     
    f == 2
    $0 == h {f=1}
    f == 1 && h2 == $0 {print h;print;f++}
' test

答案3

根据@schrodigerscatcuriosity的回答,你可以这样做

grep -zoP -- '(?s)\n---\nstart\n.*?\n---\n' file

-P用于 PCRE 扩展和(?s)fotPCRE_DOTALL

---对于您提到的和之间的可选空白行start

grep -zoP -- '(?s)\n---\n[\n\s]*start\n.*?\n---\n' file

答案4

使用用于多字符 RS 和 RT 的 GNU awk 并假设---\n仅作为记录分隔符出现在输入中(例如,您不能有b---\n中间记录之类的内容):

$ awk -v RS='---\n' -v ORS= '/^start/ && RT{print RT $0 RT}' file
---
start
a
b
c
d
---

相关内容