web-dev-qa-db-ja.com

grepを使用してパターン\\\ "を一致させる

Json内にjson文字列があります。これは複数回エンコードされ、多くのエスケープバックラッシュが発生しました:\\\"

大幅に短縮された文字列は、次のようになります。

'[{"testId" : "12345", "message": "\\\"the status is pass\\\" comment \\\\\"this is some weird encoding\\\\\""}]'

Grepを実行して、パターンの出現回数を取得しようとしています\\\"ではなく\\\\\"

どうすればいいですか?

どんなシェル/ Pythonソリューションでもいいです。 Pythonでは、検索文字列を使用します

search_string = r"""\\\\\"""、スローunexpected EOFエラー。

4
user93868

行の任意の場所で_\\\"_を検索するには:

_grep -F '\\\"'
_

つまり、正規表現の一致(バックスラッシュが特別な場合)ではなく、固定文字列検索に_-F_を使用します。また、バックスラッシュが特別ではない強い引用符(_'...'_)を使用します。

_-F_がないと、円記号を2倍にする必要があります。

_grep '\\\\\\"'
_

または使用:

_grep '\\\{3\}"'
grep -E '\\{3}"'
grep -E '[\]{3}"'
_

二重引用符で囲むと、別のレベルの円記号が必要になり、_"_を円記号でエスケープします。

_#              1
#     1234567890123
grep "\\\\\\\\\\\\\""
_

バックスラッシュは、別のシェル引用演算子です。したがって、quoteこれらのバックスラッシュと_"_文字にバックスラッシュを付けることもできます。

_\g\r\e\p \\\\\\\\\\\\\"
_

上記のgrepの文字を引用しましたが、それは必須ではありません(grepはいずれもシェルに固有のものではないためです(Bourne Shellが_$IFS_に表示される場合を除く)。シェルで特別な意味が必要なため、スペース文字は引用していません。個別の引数です。

_\\\"_を探すには、前に別の円記号が付いていない必要があります

_grep -e '^\\\\\\"' -e '[^\]\\\\\\"'
_

つまり、行の先頭、または円記号以外の文字の後に_\\\"_を探します。

その場合、正規表現を使用する必要がありますが、固定文字列検索では使用できません。

grepは、これらの式のいずれかに一致する行を返します。 1行に1つの式を使用して記述することもできます。

_grep '^\\\\\\"
[^\]\\\\\\"'
_

または1つの式のみ:

_grep '^\(.*[^\]\)\{0,1\}\\\{3\}"' # BRE
grep -E '^(.*[^\])?\\{3}"'        # ERE equivalent
grep -E '(^|[^\])\\{3}"'
_

PCREサポートを使用して構築されたGNU grep)を使用すると、後読みネガティブアサーションを使用できます。

_grep -P '(?<!\\)\\{3}"'
_

一致数を取得する

パターンに一致する(つまり、_\\\"_が1つ以上出現する)linesの数を取得するには、_-c_オプションをgrepに追加します。ただし、出現回数が必要な場合は、GNU特定の_-o_オプション(現在は他のいくつかの実装でもサポートされています)を使用して、すべての一致を1行に1つずつ出力できます。次に、_wc -l_にパイプして、行数を取得します。

_grep -Po '(?<!\\)\\{3}"' | wc -l
_

または、標準/ POSIXlyで、代わりにawkを使用します。

_awk '{n+=gsub(/(^|[^\\])\\{3}"/,"")};END{print 0+n}'
_

awkgsub()は置換し、置換の数を返します)。

12