テキストファイルから複数行を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)
fot用PCRE_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
---