Grepは0ではなく0.2ではない行を削除しますか?


12

次のような内容のファイルがあります。

0
0
0.2
0
0
0
0

単一のゼロですべての行を削除する必要があります。
を使用することを考えてgrep -v "0"いましたが、これにより0.2を含む行も削除されます。私は-wこのオプションを使用できると見ましたが、これも機能していないようです。

単一の0のみを含むすべての行を削除し、0で始まるすべての行を保持するにはどうすればよいですか?



1
@JulienLopezそれはその質問の真似ではありません。その質問は単語のマッチングに関するものであり-w、ここで失敗するで答えられます。
スパーホーク

なぜあなたgrepはこの仕事に使わざるを得ないのですか?そして、単一のゼロとは正確にはどういう意味ですか?これは、XY問題のように聞こえます
Roland Illig

1
@RolandIllig就寝時間の1時間前で、一連の500,000個の文字列の処理を開始して、それらがビットコインの秘密鍵であるかどうかを確認し、そうである場合はバランスを取得しました。次回、それを確認する時間があったので、何千もの文字列を処理し、ゼロ以外の値を解析したかっただけです。
フィリップカークブライド

回答:


35
grep -vx 0

からman grep

-x, --line-regexp
       Select only those matches that exactly match the whole line.
       For a regular expression pattern, this is like parenthesizing
       the pattern and then surrounding it with ^ and $.

-w最初の入力00.02「単語」と見なされ、したがってこの行が一致するため、失敗します。これは、「非単語」文字が後に続くためです。これを確認するには、を使用せず-vに元のコマンドを実行しますgrep -w "0"


-F正規表現パターンを使用していないため、このオプションを使用することもできます。プレーンストリングマッチングのみ
glenn jackman

@glennjackmanたぶんこれは以前読んだかもしれませんが、今は見つけられないようです。での実行-F(意外にも)には、同じくらいの時間がかかるか、わずかに遅くなる(約5〜10%)ようです。したがって、その利点が何であるかはわかりません。
-Sparhawk

2
RegExエンジンが頻繁に使用され、非常に広く使用されているため、非常に効率的なバージョンが実装されている可能性がありますが、「プレーン検索」はおそらく30年間アップグレードされていません。
ネルソン

@Sparhawk:grepメタ文字のない正規表現の特別なケースがあると思われます。これは一般的なユースケースであるためです。それは驚きだfgrep遅くなるだろうが、それは短いパターンをコンパイルしながら、この特別なケースに気付いてのオーバーヘッドが大きいファイルをスキャンする時間が無視できる対であることを驚くことではありません。(これほど高速に処理するために特別なケースが必要な場合と、文字クラスまたはx.*y。のパターンの場合。)
Peter Cordes

しかし、入力は実際には多くの短い行(1つの巨大な文字列ではない)であるため、これは多分単純化されすぎている可能性があります。改行grep以外の文字を\n行区切り文字として認識するかどうかは忘れます。そうでない場合、暗黙的で^あり、の$ ような固定文字列検索に変わりstrstr(big_buf, "\n0\n")ます。(または0\n、バッファーの開始時。)しかし、大きなバッファーに到達する可能性のある最初の一致を探しているだけでなく、効率的にフィルター処理したいのです。とにかく、理論的には、はい、それは各行の先頭にある2バイトのmemcmpです。fgrepとgrepの両方がそれを認識できることを望みます。
Peter Cordes

28

grepで:

grep -v "^0$" file

^行の始まりを意味し、行の$終わりを意味します。


2
これは、ユーザーが要求したものです。「0」が1つだけ含まれる行は避けてください。
Olivier Dulac

1
そのような二重引用符の中に文字通りのドル記号を入れません。
user541686

それはどちらかの通常最後の文字または次のいずれかのように正規表現の大きな問題があること文句を言わないということではない@mehrdad[a-Z0-9]
サンポSarrala - codidact.org

14

一方でgrep できる(他の回答を明確に示したように)このために使用すること、のステップバックを取ると、あなたが実際に欲しいものを考えてみましょう:

  • 数字を含むファイルがあります
  • 数値に基づいてフィルタリングを実行します

正規表現は、文字シーケンスデータを解釈します。彼らは数字については知らず、個々の数字(およびその通常の組み合わせ)についてのみ知っています。特定のケースでは、この制限を回避する簡単なハックがありますが、最終的には要件の不一致です。

grepここで使用する非常に正当な理由がない限り(たとえば、測定し、非常に効率的で、効率が重要な場合)、別のツールを使用することをお勧めします。

awkたとえば、次のような数値比較に基づいてフィルタリングできます。

awk '$1 == 0' your_file

ただし、ゼロより大きい数値を含むすべての行を取得するには、次のようにします。

awk '$1 > 0' your_file

正規表現が大好きです。素晴らしいツールです。しかし、それだけがツールではありません。ことわざにあるように、あなたが持っているものがすべての場合grep、すべてが通常の言語のように見えます。


3
ここではawkの方がエレガントかもしれないと心から同意します...しかし、ユーザーが期待するよりも少しだけ一致することもあります(すべての数値が0と評価されます)。つまり、printf '0\n1\n-1\na\nb\n0\n0 also\n0.0\n-0.0\n0*0\n' | awk '($1 == 0)'と一致します:00.0および-0.0...と0 also!「0」だけではありません。(必要な場合もあれば、そうでない場合もあります)。ユーザーが「0」のみを必要とする場合:(awk '/^0$/' またはgrep '^0$')。また、編集する必要があります。ユーザー!はテストを無効にするために追加する必要があるため0、残りを非表示(および他のゼロ)に表示します。例:awk '!( $0 == 0)'
オリビエデュラック

1
@Olivier、または文字列値を確認します$1 == "0"
グレンはジャックマン

1
@OlivierDulac これは、同等ではなく任意の数値比較であることを強調する>ために!=(または同等に! (… == …))ではなく明示的に使用しました。あなたの他のコメントについては、これは完全に真実ですが、その後、基本的に文字列比較の領域とgrep作品を使用した既存のソリューションに戻ります(awkもちろん、作品も機能します)。
コンラッドルドルフ

@KonradRudolphフェアポイント:)
オリビエデュラック

1
@glennjackman:確かに素晴らしいトリックです。しかし、OPはむしろテストを行います$0=="0"
オリビエデュラック

5

grepさんは、-wそれが単語と非単語の構成要素(文字、数字またはアンダースコア以外のもの)に、元の文字列を分割する方法で回旋ビットです。すでに有効な単語構成要素0に遭遇している0.02ため、その行を削除するために否定ロジックがアサートされていました。

sedこのコンテキストでは、使用するのは簡単です。一致する単語全体を削除するだけです

sed '/^0$/d' file

3

行は削除したいときにだけ含まれている0 次の行に続いて次のコマンドを発行して、それらの行を選択することができます。

grep -v "^0$"

これはのみの出現に印刷されます0されている行の終わり、行の先頭に同時にします。この-vオプションは選択を反転します。


1
この答えはArkadiusz Drabczykのものとほとんど同じですが、を忘れてしまった-vため、動作しません。
スパーホーク

あなたが正しい。彼が彼の答えを投稿している間私はタイプしていたので、それがすでに与えられているのを見ませんでした。その部分を-vオプションで読み間違えました、ありがとう!
majesticLSD

0
  • \ b-ワードボーダー

grep -v "\b0\b"

  • 行頭、パターン、行末に一致

grep -v "^0$"

  • または@Sparhawkが示唆したように-vx lineregexp

-wは機能しますが、ドット文字は単語の区切り文字であるため、0.2は2つの単語です。


grep -v "\b0\b"ここでは実際には機能しません。どのバージョンのgrepを使用していますか?
Arkadiusz Drabczyk

作品grep (BSD grep) 2.5.1-FreeBSDMacOSの上やgrep (GNU grep) 2.16Ubuntuで
ヤクブJindra

1
GNU正規表現を使用\<して\>単語の境界として、それは同じ効果があります-w
グレンはジャックマン

0

PCREが有効になっていると仮定すると、多様性のための別の答え grep

grep -Pv "^0(?!\.)"

これは、実行否定先読みで始まる行と一致する0されていないドットが続いています。次に-v、一致しない行を破棄します。あなたはここで実際に見ることができます


1
これにより0123、OPなどが必要としないのような行も削除されます
iruvar

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.