web-dev-qa-db-ja.com

特定の列に特定の値を持つ行をgrepする方法は?

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

  200.000    1.353    0.086
  200.250    1.417    0.000
  200.500    1.359    0.091
  200.750    1.423    0.000
  201.000    1.365    0.093
  201.250    1.427    0.000
  201.500    1.373    0.093
  201.750    1.432    0.000
  202.000    1.383    0.091
  202.250    1.435    0.000
  202.500    1.392    0.087
  202.750    1.436    0.000
  203.000    1.402    0.081
  203.250    1.437    0.001
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045  

最初の列に10進数の.000と.500のみがある行のみをgrepしたいので、出力は次のようになります。

  200.000    1.353    0.086
  200.500    1.359    0.091
  201.000    1.365    0.093
  201.500    1.373    0.093
  202.000    1.383    0.091
  202.500    1.392    0.087
  203.000    1.402    0.081
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045  
9

あなたはgrepを使いません。 awkを使用します。

"your data" | awk '$1 ~ /\.[05]00/'
14
azzid
awk '$1 ~ /\.[50]00/ { print $0 }' myFile.txt

最初の列$1/\.500|\.000/と照合されます。ドットはエスケープされてリテラルドットにならず、~は部分一致であり、行全体を印刷します$0

4
Dalvenjia

grep最初の列に10進数の.000および.500が含まれる行のみを表示したい

私の最初の考え

grep '^ *[0-9][0-9][0-9]\.[50]00' filename

WSLを使用したクイックテスト

$ head testdata
              200.000    1.353    0.086
              200.250    1.417    0.000
              200.500    1.359    0.091
              200.750    1.423    0.000
              201.000    1.365    0.093
              201.250    1.427    0.000
              201.500    1.373    0.093
              201.750    1.432    0.000
              202.000    1.383    0.091
              202.250    1.435    0.000
$ grep '^ *[0-9][0-9][0-9]\.[50]00' testdata
              200.000    1.353    0.086
              200.500    1.359    0.091
              201.000    1.365    0.093
              201.500    1.373    0.093
              202.000    1.383    0.091
              202.500    1.392    0.087
              203.000    1.402    0.081
              203.500    1.412    0.073
              204.000    1.423    0.065
              204.500    1.432    0.055
              205.000    1.441    0.045

これを表現するより簡潔な方法があります。

$ grep -E '^ *[0-9]{3}\.[50]00' testdata
              200.000    1.353    0.086
              200.500    1.359    0.091
              201.000    1.365    0.093
              201.500    1.373    0.093
              202.000    1.383    0.091
              202.500    1.392    0.087
              203.000    1.402    0.081
              203.500    1.412    0.073
              204.000    1.423    0.065
              204.500    1.432    0.055
              205.000    1.441    0.045

最初の列に3桁以外の整数部分がある場合

grep -E '^ *[0-9]+\.[05]00' testdata

状況によっては、[:digit:] 代わりに [0-9]

等々。

man grep あなたの友だちです。

4
RedGrittyBrick

OK、少し遅れて私の貢献を追加しましたが、それだけの価値があると思います。

OPごとに満たす必要があるのは、10進値が_.000_または_.500_のみの最初の列です。範囲または長さのどちらでも、主要な値に関する規定はありません。堅牢性のために、最初の列の前に非空白文字がない(または最初の列ではなくなった)こと、および最初の列の内容willを除いて、何によっても制約されていると想定しないでください。 =どこかに小数点がある、_._。

OPはgrepを使用しようとしています。これは一致が見つかったときに行全体を出力するため、実行する唯一のことはallおよびに一致するパターンを作成することです。のみ必要なもの。

それ自体が単純で、sedまたはawkを使用する理由はありません。`grepはソースをファイルまたはパイプとして処理できるためです。

ファイルをgrepするには、_grep '^[^.]*\.[05]0\{2\}\s' the_file.txt_を使用します

パイプからgrepするには、_my_command | grep '^[^.]*\.[05]0\{2\}\s'_を使用します

パターンは次のとおりです。_^_、行の先頭から開始します。 _[^.]_、10進数以外の文字と一致します。 _*_、できるだけ多く(なしを含む)。 _\._、小数点に一致。 _[05]_、5または0のいずれかに一致。 _0\{2\}_、さらに2つのゼロに一致します(開き括弧と閉じる括弧の前のバックスラッシュは、シェルが括弧の拡張を試みないようにします); _\s_、空白文字に一致します(列の終わりを意味します-別のユースケースで使用するには、列区切り文字、通常はコマンド、セミコロン、またはタブに置き換えます_\t_) 。

これはexactly OPが要求したものと一致することに注意してください。 notは、数値的に同等であっても_.5000_または_.0000_に一致します。これは、パターンが5または0を検索し、その後に正確に2 moreが続くためですゼロとそれに続く空白。それが重要である場合、これまでの他のすべての回答は、テストディジットの後に、1より大きいゼロの任意の数と一致するという点で失敗します。そしてFloHimselfによる回答を除いて、それらは2番目の列でanythingと一致しますbegins _.000_または_.500_、_.0003_を含むおよび_.500T_、およびFloHimselfによるものは、ゼロがいくつあっても、_.0_および_.5_と数学的に同等なものと一致します。最後のものは、OPが述べたものと一致しませんが、いずれにしてもOPが必要とするものと一致する可能性があります。

最後に、OPがawkを要求した場合でも、grepのパワーと速度が必要な場合、コマンドは次のようになります。

ファイルあり_awk '$1 ~ /[^.]\.[05]0{2}$/' the_file.txt_

パイプ付き_my_command | awk '$1 ~ /[^.]\.[05]0{2}$/'_

2
user207673

ユースケースによっては、実際の数値演算を使用することもできます。

$ awk '{a = $1 % 1} a == 0 || a == 0.5' /tmp/foo
  200.000    1.353    0.086
  200.500    1.359    0.091
  201.000    1.365    0.093
  201.500    1.373    0.093
  202.000    1.383    0.091
  202.500    1.392    0.087
  203.000    1.402    0.081
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045

BSD awk(OSX El Capitan、20070501)およびGNU awk 4.1.4。

2
muru
 grep -e '2[^ ]*.000' -e '2[^ ]*.500' file.txt
2
prince 987

awkの場合:

$>awk '$1%.5==0' data.tsv 
200.000 1.353   0.086
200.500 1.359   0.091
201.000 1.365   0.093
201.500 1.373   0.093
202.000 1.383   0.091
202.500 1.392   0.087
203.000 1.402   0.081
203.500 1.412   0.073
204.000 1.423   0.065
204.500 1.432   0.055
205.000 1.441   0.045

mlr の場合:

$>mlr --ifs tab --onidx filter '$1%.5==0' data.tsv 
200.000 1.353 0.086
200.500 1.359 0.091
201.000 1.365 0.093
201.500 1.373 0.093
202.000 1.383 0.091
202.500 1.392 0.087
203.000 1.402 0.081
203.500 1.412 0.073
204.000 1.423 0.065
204.500 1.432 0.055
205.000 1.441 0.045
2
FloHimself

Grepの使用を主張する場合、これでうまくいくかもしれません。提供した最初の出力を "file.txt"というテキストファイルに保存し、次のコマンドを使用しました。

grep -e '2[^ ]*.000' file.txt & grep -e '2[^ ]*.500' file.txt

次の出力が得られます。

200.000    1.353    0.086
200.500    1.359    0.091
201.500    1.373    0.093
201.000    1.365    0.093
202.500    1.392    0.087
202.000    1.383    0.091
203.500    1.412    0.073
203.000    1.402    0.081
204.500    1.432    0.055
204.000    1.423    0.065
205.000    1.441    0.045

既にファイル内にある場合は、出力をテキストファイルに保存する必要はありません。ただし、ファイルに保存されていない場合は、提供したgrepコマンドにデータをパイプすることもでき、少なくとも最初の列の最初の数値2がaでなくなるまで機能します。 2。この時点で、正しく印刷するには、適切な文字でgrepコマンドを更新する必要があります。

このデュアルgrepコマンドで起こっていることは、最初のgrep&演算子を使用してバックグラウンドに送信されていることです。バックグラウンドに送信されると、次のgrepコマンドがすぐに実行され、統一された出力が得られます。完了しなければならないタスクをより簡単に実行するには、他の人が与えた例に従い、awkまたはsedを使用する必要があります。

(編集)

これは決してあなたのニーズに合ったgrepの最良または最も効果的な使用法ではありませんが、少し遊んでgrepをよりよく感じるには十分なはずです。

1
Yokai