長い文章でまとめます。
(foo),(bar,baz(word,right),(end)
私は印刷したいだけです:
(bar,baz(word,right
2番目の角かっこを一致させるために、入らないようにする3番目の単語に続く単語:
$ grep -oP "\\(.*(?!word).*right"
しかし、Bashは感嘆符を説明します。
-bash: !word: イベントが見つかりません
感嘆符の保護アポストロフィ失敗したgrep: missing )
$ grep -oP '\\(.*(?!word).*right'
$ grep -oP '\\((?!word)(.*right)'
感嘆符の保護バックスラッシュ失敗したgrep: unrecognized character after (? or (?-
どんなアイデアがありますか?
注:-P
Perl正規表現の場合、-o
行の一致部分のみが印刷されます。
答え1
一重引用符と二重引用符の規則は異なります。
表示された理由で感嘆符をエスケープするための合理的な方法がないため、bashは二重引用符を確実に使用できません。
$ grep -oP "\\(.*(?!word).*right"
bash: !word: event not found
$ grep -oP "\\(.*(?\!word).*right"
grep: unrecognized character after (? or (?-
2つ目はbashがgrepの\!
代わりに渡すからです!
。これを見せてください:
$ printf '%s' "\!"
\!
一重引用符を使用しようとすると、二重バックスラッシュはエスケープされたバックスラッシュを意味するのではなく、2つのバックスラッシュを意味します。
$ printf '%s' '\\(.*(?!word).*right'
\\(.*(?!word).*right
一重引用符内では、すべてが文字通りエスケープされていないため、試したい正規表現を作成する方法は次のとおりです。
$ grep -oP '\(.*(?!word).*right'
答え2
2番目の開き括弧から次の閉じ括弧まで(含まれていない)一致させる場合:
grep -Po '\(.*?\K\([^)]*'
またはポータブルで使用してくださいsed
。
sed -n 's/^[^(]*([^(]*\(([^)]*\).*/\1/p'
(
一番右の項目が後続しない一番右の項目と一致するには、次の手順を実行しますword
。right
grep -Po '.*\K\((?!word).*right'
答え3
簡単な方法でこれを行うことができますawk
。
$ echo '(foo),(bar,baz(word,right),(end)' | awk -F'),' '{print $2}'
(bar,baz(word,right
答え4
何らかの理由でMikelの回答で提案されているように単一引用符を使用できない場合は、Glenn jackmanがコメントで提案したように履歴拡張を一時的に無効にするために使用できますset +H
(openorを使用)。set -H