特定の文字または文字セットで始まる行を削除する方法については、sedの例をたくさん読んでいましたが、それほど難しくありませんが、この例を解読することはできません。ファイル内の文字「i」で始まり、「.conf」で終わらない行をすべて削除したいと思います。
以下は例のリストです。
include /usr/local/choops/users/2488.conf
include /usr/local/cho
include /usr/local/choops/users/2492.conf
i
incl
上記の例で削除する3行は次のとおりです。
include /usr/local/cho
i
incl
それらは不完全であり、そこにはありません。
StackExchange、StackOverflow、その他のさまざまなフォーラムで、この例のいくつかのバリエーションを試しましたが、正しく理解できないようです。私が試したことは次のとおりです。
sed -i '/^i.*[^\.conf]$/d' /usr/local/choops/users/main.conf
sed -i '/^i.\*\[^\\.conf\]$/d' /usr/local/choops/users/main.conf
sed -i '/^i.*[^.conf]$/d' /usr/local/choops/users/main.conf
ここで、main.confは、上記のように.confファイルセットを一覧表示するファイルです。私はこれがあまりにも複雑ではないと思いましたが、これらのコマンドのどれも私には機能しないようです。さまざまなソースとsedの理解に基づいてコマンドを構築しました。どんな助けでも大変感謝します。とても混乱しています。
以下は私が望むものとは反対ですが、簡単だと思います。
sed -i 's/i.*.conf//' main.conf
答え1
同時に満たす必要がある2つの条項があります(「iで始まる」、「.confで終わらない」)。出力から行を除外するには、各句を個別にテストしてから組み合わせる必要があります。
入力例(「i」で始まらない追加の行を追加):
$ cat input.txt
include /usr/local/choops/users/2488.conf
this line doesn't begin with i
include /usr/local/cho
this line doesn't begin with i but does end in .conf
include /usr/local/choops/users/2492.conf
i
incl
そしてperl
:
$ perl -ne 'print unless (/^i/ && ! /\.conf$/)' input.txt
include /usr/local/choops/users/2488.conf
this line doesn't begin with i
this line doesn't begin with i but does end in .conf
include /usr/local/choops/users/2492.conf
そしてsed
:
$ sed -ne '/^i/ {/\.conf$/!d;};p' input.txt
include /usr/local/choops/users/2488.conf
this line doesn't begin with i
this line doesn't begin with i but does end in .conf
include /usr/local/choops/users/2492.conf
または@seshoumaraが提案したように(おそらくより良いでしょう):
sed -e '/^i/ {/\.conf$/!d;}' input.txt
3つのバージョンすべてが出力から不要な行を削除し、他のすべての内容を印刷します。
答え2
行が「i」で始まる場合はtrue、行が「.conf」で終わらない場合はtrueという2つの条件があるようです。一度に検索するのではなく、2回にわたって検索してください。
sed -i '/^i/{/\.conf$/!d}' /usr/local/choops/users/main.conf
それともその逆なら否定してください。
sed -i '/^i.*\.conf$/!d' /usr/local/choops/users/main.conf
ポイントはエスケープする必要があります。それ以外の場合は、任意の文字を表す正規表現になります。
実際に試している「[^abc]」正規表現は、「a」、「b」、または「c」ではない単一文字を意味します。 「j」または「z」のいずれかです。この正規表現が何と一致していても、まだ単一の文字です。最後に、「[]」または「[^]」の文字は正規表現の意味を持つことはできず、リテラル文字のリストにすぎず、「.」は常にドットを意味するため、エスケープする必要はありません。しかし、//またはs///では、状況に応じてエスケープしたいです。
答え3
文字「i」で始まり、「.conf」で終わらないファイルのすべての行を削除したいと思います。
A
「と言いましょう。文字で始まるi
」B
「と言いましょう。次に終わる.conf
」
使用ブール論理「AでBではない」条件に一致する行を削除すると言うことができます。
A . B'
また、これを「{AまたはBではない}の否定」として書き換えることもできます。
( A' + B'' )' = ( A' + B )'
これを使用すると、grep
これを次のように置き換えることができます。維持する(削除する代わりに)式に一致する行は次のとおりです。
( A' + B )
コードではこうなります。
grep -E '^[^i]|\.conf$'
実際には、まったく文字で始まらない行(つまり空白)も考慮する必要があります。
grep -E '^[^i]|\.conf$|^$'
サンプルファイルを使用すると、次の行を保持できます。
include /usr/local/choops/users/2488.conf
include /usr/local/choops/users/2492.conf
内部編集(煙とミラー)には一般的な規則が適用されるため、直接適用します。
grep ... file >file.tmp &&
mv -f -- file.tmp file
rm -f -- file.tmp
答え4
begin with the letter "i" and DO NOT end with ".conf"
awkを使用すると、指定した一致要件を削除したい行を識別するコードに簡単に変換できます。
$ awk '/^i/ && !/\.conf$/' file
include /usr/local/cho
i
incl
次に、維持したい行を取得するには、条件を無効にします。
$ awk '!(/^i/ && !/\.conf$/)' file
include /usr/local/choops/users/2488.conf
include /usr/local/choops/users/2492.conf
必要に応じて、次のように短縮できます。ドモーガンの法則到着する:
$ awk '!/^i/ || /\.conf$/' file
include /usr/local/choops/users/2488.conf
include /usr/local/choops/users/2492.conf