有谁知道如何从文本文件中 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
---