grep -E
負のスペースを使用すると、期待どおりに機能しないのはなぜですか?つまり[^\s]+
私の構文を分析するために正規表現を作成しました。.ssh/config
grep -Ei '^host\s+[^*\s]+\s*$' ~/.ssh/config
# cat ~/.ssh/config
Host opengrok-01-Eight
Hostname opengrok-01.company.com
Host opengrok-02-SIX
Hostname opengrok-02.company.com
Host opengrok-03-forMe
Hostname opengrok-03.company.com
Host opengrok-04-ForSam
Hostname opengrok-04.company.com
Host opengrok-05-Okay
Hostname opengrok-05.company.com
Host opengrok-05-Okay opengrok-03-forMe
IdentityFile /path/to/file
Host opengrok-*
User root
私が得るものは
Host opengrok-01-Eight
Host opengrok-03-forMe
Host opengrok-05-Okay
Host opengrok-05-Okay opengrok-03-forMe
シックスとサムはどこにありますか!
[^\s*]+
つまり、空白でないか*
、1以上でない項目と一致するのが実際に、、\
1以上でない項目と一致することに気づくのに時間がかかりました!s
*
正規表現はrex101.com(perlを使用)で動作するため、修正は非常に簡単です。つまり、-E
スイッチ-P
# grep -Pi '^host\s+[^*\s]+\s*$' ~/.ssh/config
Host opengrok-01-Eight
Host opengrok-02-SIX
Host opengrok-03-forMe
Host opengrok-04-ForSam
Host opengrok-05-Okay
私が恐れていたのは、私がgrep -E
長年にわたって多くのスクリプトでこれを使用してきましたが、以前はこれを見つけることができなかったことです。たぶん幸運だったかもしれませんが、私のテストケースがその極端なケースを逃した可能性が高くなります!
質問:
grep -P
すべての拡張正規表現で使用するように変更することに加えて、grep -E
この場合は正規表現をどのように書くべきですか?- 私が見逃したり
-E
使用したりすると迷惑になる他の問題がありますか-P
?
grep (GNU grep) 3.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.
Windows 10 で実行中、Ubuntu 18.04(bash) を実行する WSL... が、適切な Linux インストールでも同じ結果が得られます。
答え1
の補数は、\s
is \S
、not [^\s]
which(の助けを借りて-i
) 'SIX'および 'Sam'にリテラルが含まれているため、結果から除外されますs
。
grep -i
「ホスト」で始まり、1つ以上のスペースと行の終わりまで続く1つ以上の文字シーケンス(*
単語やスペースが存在できない)を処理する方法:
grep -Ei '^host[[:space:]]+[^*[:space:]]+$' file
Host opengrok-01-Eight
Host opengrok-02-SIX
Host opengrok-03-forMe
Host opengrok-04-ForSam
Host opengrok-05-Okay
答え2
空白の解釈は\s
GNU Grepの拡張です。定義されていませんPOSIX。BSDクエリたとえば、\s
スペースは認識されません。 Perl正規表現もPOSIX拡張ですが、BSDとGNUの両方を提供します。完全に移植可能な式の場合は使用する必要があります[[:space:]]
。
GNU Grep マニュアルややゆるく言うと、「ほとんどのメタ文字は角括弧式内で特別な意味を失います」。あなたはこれが\s
それらの1つであり、実際には次のように作られたことを発見しました。POSIX(やはり)特殊文字、、、および.
は*
角[
括弧\
式で特別な意味を失う必要があります。しかし、まだポータブルで使用できます[:space:]
。
それでは、2つの質問に答えると、
grep -E
このイベントのエッセイはどのように書くべきですか?
grep -Ei '^host[[:space:]]+[^*[:space:]]+[[:space:]]*$'
私が見逃したり
-E
使用したりすると迷惑になる他の問題がありますか-P
?
.*?
よくある間違いは、フラグなしで貪欲ではないPerlを試すことです-P
。
$ echo 'AB 14 34' | grep -Eo '^.*?4'
AB 14 34
$ echo 'AB 14 34' | grep -Po '^.*?4'
AB 14
$ echo 'AB 14 34' | grep -o '^.*?4'
{nothing}
最後の文章:BREとEREPREとは異なります。正規表現を学びましょう!