次の内容を含むfile2.txtファイルを検討してください。
P 89 24 -1.5388040474568784e+01 7.4421775186012660e+00 -1.3143195543234219e+03 1.3168884860257754e+03 8.0419002445999993e+01 44 0 0 -97 0
P 122 -4 -1.4869334602986523e+01 5.7316939411954255e+00 -1.3144161801429666e+03 1.3169704096915282e+03 8.0419002445999993e+01 44 0 0 -370 0
P 493 -24 -1.4690576431881317e+01 7.3848907323212831e+00 -1.3144620647251766e+03 1.3170224315489374e+03 8.0419002445999993e+01 62 0 0 -499 0
E 3 -1 -1.0000000000000000e+00 -1.0000000000000000e+00 -1.0000000000000000e+00 9999 0 970 1 2 0 7 1.7003962000000002e+05 8.5019810000000018e-01 8.5019810000000018e-01 8.5019810000000018e-01 3.0000000000000000e+01 3.8153441026312507e+01 1.0000000000000000e+11
E 4 -1 -1.0000000000000000e+00 -1.0000000000000000e+00 -1.0000000000000000e+00 9999 0 818 1 2 0 7 1.7003962000000002e+05 8.5019810000000018e-01 8.5019810000000018e-01 8.5019810000000018e-01 3.0000000000000000e+01 3.2509364886711985e+01 1.0000000000000000e+11
P 5 2 0 0 3.7531787088999999e+02 3.8383684055052936e+02 8.0419002445999993e+01 22 0 0 -6 0
P 8 24 7.0195398693654170e+00 3.1543502387874696e+01 5.5989200759599044e+01 1.0318077843755555e+02 8.0419002445999993e+01 44 0 0 -50 0
P 67 28 5.8271676589304882e+00 3.3476871962084061e+01 5.6723118833601163e+01 1.0411236719963519e+02 8.0419002445999993e+01 44 0 0 -168 0
P 219 13 6.0328453988772415e+00 3.3531592253635168e+01 5.6777179460595200e+01 1.0417114266715717e+02 8.0419002445999993e+01 44 0 0 -329 0
P 444 -24 6.4646967953734418e+00 3.4909545978243479e+01 5.7879920796889749e+01 1.0525098522544691e+02 8.0419002445999993e+01 62 0 0 -452 0
E 5 -1 -1.0000000000000000e+00 -1.0000000000000000e+00 -1.0000000000000000e+00 9999 0 598 1 2 0 7 1.7003962000000002e+05 0 0 8.5019810000000018e-01 3.0000000000000000e+01 6.8997318544430456e+01 1.0000000000000000e+11
私は文字列またはP ... 24 ...
を抽出したいだけですP ... -24 ...
。これが私がしたことです:
cat file2.txt | grep -E '(P [0-9]+ 24 | P [0-9] + -24 |P [0-9][0-9]+ 24 | P [0-9][0-9] + -24 |P [0-9][0-9][0-9] + 24 | P [0-9][0-9][0-9] + -24 |P [0-9][0-9][0-9][0-9]+ 24 | P [0-9][0-9][0-9][0-9] + -24 )' &> file3.txt
ただし、生成されたfile3.txtには文字列のみが含まれていますP ... 24
。何が間違っているのか教えてもらえますか?
答え1
....私は何が間違っていましたか? ...より複雑にすることに加えて、...すべての場合-24
と異なる場合に文字列に含まれていない複数のスペースと先行スペースを一致させようとしています...
P [0-9]+ 24 |
わかりましたP
。一連の数字
[0-9]+
とスペース
24
を順番に入力します。
| P [0-9] + -24 |
ここの数字の前と後には1つ以上のスペースがあり、その後には余分なスペースがあるため一致しない別のスペースが続きます。
P
+
|P [0-9][0-9]+ 24 |
もう一度うまくいきますが、すべての一致がすでに最初のパターンでキャプチャされているため、重複しています。
| P [0-9][0-9] + -24 |
追加のスペース、上記と同じ-24
...一致しません
|P [0-9][0-9][0-9] + 24 |
以前は空きスペースがあったので、また2つ以上+
探してみました。
| P [0-9][0-9][0-9] + -24 |
the の前には先行スペースがあり、再びP
2 つ以上のスペースが前に続きます。-24
|P [0-9][0-9][0-9][0-9]+ 24 |
すばらしいが重複
| P [0-9][0-9][0-9][0-9] + -24
the の前には先行スペースがあり、再びP
2 つ以上のスペースが前に続きます。-24
@gillesquenotはよりエレガントなソリューションを提供しますが、余分なスペースを失ってもソリューションは「動作」します。
grep -E '(P [0-9]+ 24 |P [0-9]+ -24 |P [0-9][0-9]+ 24 |P [0-9][0-9]+ -24 |P [0-9][0-9][0-9] + 24 |P [0-9][0-9][0-9]+ -24 |P [0-9][0-9][0-9][0-9]+ 24 |P [0-9][0-9][0-9][0-9]+ -24 )'
複数のスペースが利用可能な場合
grep -E '^P +[0-9]+ +-?24'
編集する
これ文字列内の一致内容と位置を確認するのに便利なリソースです。
答え2
ミッションのようです。アッ!これはDSL1: これがすぐにawk
行く道です。
シンプルで再利用が可能で、効率的で高速です。
いいえ正規表現:
awk '$1 == "P" && ($3 == "-24" || $3 == "24")' file2.txt
または使用正規表現:
awk '$1 == "P" && $3 ~ /^-?24$/' file2.txt
ここで、正規/^-?24$/
表現ではダッシュはオプションなので、この短い文字を使用できます。正規表現。
正規表現の一致は次のとおりです。
節 | 説明する |
---|---|
^ |
文字列の始まり |
-? |
'-'(オプション(最大の一致)) |
24 |
「二十四」 |
$ |
オプションの\nの前と文字列の終わり |
1 最も有名なチャットに質問をする
Q:DSLは開発者にとって何を意味しますか?
DSL(ドメイン固有の言語)は、特定のタスクをより簡単にコーディングできるように設計されたコンピュータ言語です。特定のアプリケーションドメインに合わせて調整し、開発者が迅速かつ効率的にコードを書くことができます。 DSLの一般的な用途には、データベースクエリ、テキスト処理、および科学シミュレーションが含まれます。 DSLを使用すると、開発者は特定の目的のためにアプリケーションを迅速に構築し、より直感的なプログラミングアプローチを提供し、構文への依存を減らすことができます。
答え3
正規表現を少し単純化してみましょう。
grep -E '^P [0-9]+ -?24\b' file2.txt
望ましくない複雑さと可読性に加えて、正規表現の主な問題は、間違った空白をさらに使用することです。
不要:
cat | grep
を使用してください。猫の無駄な使用multiple|regex
ここで使用してください
入力にさらに多くのスペースがあると思われる場合は、次のいずれかを使用できます。
+
[[:space:]]+
(POSIX
文字クラス)\s+
-P
別名PCRE
スイッチが必要grep
正規表現の一致は次のとおりです。
節 | 説明する |
---|---|
^ |
線基準点の始点 |
P |
「P」+スペース |
[0-9]+ |
すべての文字:「0」〜「9」(1回以上(最大限一致)) |
|
スペース |
-? |
'-'(オプション(最大の一致)) |
24 |
「二十四」 |
\b |
単語の境界 |
答え4
まあ、値が24である可能性がある1つのフィールドにのみ依存しているのです。これは間違った設計のように見えます。たとえば、さらにcut
分析するために、そのファイルから最初と3番目の列を抽出するためのツールがたくさんあります。
しかし、正直に言うと、これはまたはsed
などのcut
文字列エンジンではなく、表形式の数値データを処理するツールの作業ですgrep
。
正直に言うと、数行のPython(またはPerlまたは...必要なプログラミング言語)がこの問題を解決します。とにかく、ここで結果をプログラム的に処理すると100%確信しています。スタート言語から。
簡単に説明すると、次のようになります。
#!/usr/bin/env python3
import sys
with open(sys.argv[1], "r", encoding="ascii") as inputfile:
linecounter = 0
for line in inputfile:
linecounter += 1
try:
if not line.startswith("P "):
continue # skip this line alltogether
thirdpos = int(line.split(" ")[2])
if not (thirdpos == 24 or thirdpos == -24):
continue
print(line) # or actually, do something useful with the line
except Exception as e:
print("Exception occurred on line {linecounter}, '{line}':\n{e}", sys.stderr)
テキストファイルでchmod 755 thatfile
、を実行してから/path/to/thatfile /path/to/input_file
。