「POSIX BRE」または「POSIX ERE」正規表現を使用して文字列(行または単語)を一致させる方法いいえbak
ありますか?
最後に、ファイル名を持たls | egrep '<regex>'
ないすべてのファイルを見つけることを作成したいと思います。bak
file1
たとえば、、、、、file2_bak
および3つのファイルがある場合、bak_file3
正規表現はfile1
andにのみ一致する必要がありますbak_file3
(は一致しませんfile2_bak
)。
を使用して実行できることを知っていますが、orオプションを使用せずに実行したいとls | grep -v 'bak$'
思います。-v
これはPOSIX正規表現の理論的/学術的問題であるため、使用したくありません。grep
egrep
-v
bak
最後にファイル名を一致させる方法は次のとおりです。
$ ls | egrep 'bak$'
file2_bak
$
上記の正規表現は、bak$
最後に文字列があるすべての文字列と一致します。bak
しかし、すべての文字列に一致する正規表現をどのように書くのですか?するいいえ持つ bak
最後に?
答え1
答え2
一般言語(「REと一致する可能性がある」など)は補完語の下に閉じられているため、可能ですが、実用的な目的にはあまり役に立ちません。条件付きで始まります。
最後の文字はANDです
k
。前の文字はANDです。a
前の文字はANDです。b
(Python方式で作成しますs[-1]=='k' and s[-2]=='a' and s[-3]=='b'
) したがって、失敗した文字列は
not(s[-1]=='k' and s[-2]=='a' and s[-3]=='b')
つまり
not(s[-1]=='k') or not (s[-2]=='a' and s[-3]=='b'))
つまり
not(s[-1]=='k') or not(s[-2]=='a') or not(s[-3]=='b')
もちろん、DeMorganのルールを2回適用します。これは、文字列の長さが2以下の場合に特に当てはまります。したがって、おおよそ次のような結果が得られる。
grep '^$\|^.$\|^..$\|..[^k]$\|.[^a].$\|[^b]..$'
私はそれが型付け可能ですが、メンテナンスは不可能だと思います。
(理論的側面のメモ:通常、正規表現を決定論的有限自動デバイス(DFA)に変換し、最終状態を反転してから、新しいDFAをすべて明確に定義された正規表現に戻すことができます。多少退屈でエラーが発生する簡単なプロセスです)。
答え3
使用find
:
find . -maxdepth 1 -type f ! -name "*bak"
.
:現在の作業ディレクトリから検索するようにアサーションします。-maxdepth 1
:指定されたディレクトリの下の1つのレベルのみを取得するように指定します(つまり、現在の作業ディレクトリのみ)-type f
:ファイルのみ検索すると主張! -name "*bak"
:次に終わらないファイル名だけを検索すると主張します。bak
grep
ls
しかし、出力が必要な場合:
ls | grep -v 'bak$'
-v
:与えられた正規表現と一致しない行だけを印刷します。
正規表現の分解:
bak
:bak
文字列と一致します。$
: 行末と一致
否定的な振り返りを使用する場合も同様です(PCRE
s互換grep
バージョンの場合)。
ls | grep -P '(?<!bak)$'
-P
PCRE
:s を使用して行を一致させます。
正規表現の分解:
(?<!bak)
: 前に文字列がない場合は、次のbak
パターンのみが一致します。$
: 行末と一致
答え4
Perl拡張がある場合は、否定予測を使用できます。
grep -P '^.{0,2}$|^.*(?!bak)...$'
bakで終わらない行を一致させるために使用されます。