Shell
雙引號和單引號內的Grep字元串
我想在文本文件中找到雙引號或單引號內的字元串(文本文件是多行的),
例如:
I have a test "foo bar1" test2 "foo\"bar2", "foo 'bar3", 'foo bar4', 'foo \'bar5', 'foo "bar6',
它會輸出
foo bar1 foo\"bar2 foo 'bar3 foo bar4 foo \'bar5 foo "bar6
難點是:
- 文本文件是多行的。
- 它可能在引號內轉義了雙引號或單引號。
- 雙引號裡面可能有單引號。
- 單引號裡面可能有雙引號。
- 引號必須成對匹配。
我們可以使用 Perl 的匹配時間程式碼插值功能
(??{ match time regex })
來解決這個問題。本質上,它所做的是,根據匹配的引用,它將相應的有效正則表達式放置在該引用中,以便正則表達式引擎將獲取該引用對。$ perl -lne ' print substr($&, 1, -2+length($&)) while /(?:(["'\''])(??{q<(?:[^\\\\>.$1.q<]|\\\\.)*>.$1}))/gx; ' file
結果:
foo bar1 foo\"bar2 foo 'bar3 foo bar4 foo \'bar5 foo "bar6
上面的更平滑的重寫如下:
$ perl -lne ' BEGIN { $genRE = sub { my $openingQ = shift; # look in the Notes below for why qq<(?:[^\\\\${openingQ}]|\\\\.)*> }; } print $2 while / (["'\'']) (?#: opening quote) ((??{ $genRE->($1) })) (?#: run of in between quote pair stuff) \1 (?#: corresponding closing quote) /gx; ' file
筆記::
"........"
被匹配/"[^"]*"/
"...... \"......"
被匹配/"(?:[^\\"]|\\.)*"/
- 單引號也類似。