考虑文件 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 仅包含 strings P ... 24
。你能告诉我我做错了什么吗?
答案1
.... 我究竟做错了什么? ...除了使它变得更加复杂之外...您正在尝试匹配在所有情况下-24
以及在其他一些情况下不在字符串中的多个空格和前导空格... 。
P [0-9]+ 24 |
可以P
,然后是一系列数字
[0-9]+
,然后是
24
空格
| P [0-9] + -24 |
这里的数字之前和之后有一个或多个空格,后跟另一个空格,由于额外的空格而无法匹配
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
似乎是一个任务awk!这是DSL1:这正是awk
要走的路。
简单、可重复使用、高效且快速。
没有正则表达式:
awk '$1 == "P" && ($3 == "-24" || $3 == "24")' file2.txt
或使用正则表达式:
awk '$1 == "P" && $3 ~ /^-?24$/' file2.txt
这里,在正则表达式中/^-?24$/
,破折号是可选的,它允许使用这个短的正则表达式。
正则表达式匹配如下:
节点 | 解释 |
---|---|
^ |
字符串的开头 |
-? |
'-'(可选(匹配尽可能多的数量)) |
24 |
‘24’ |
$ |
在可选的 \n 之前和字符串末尾 |
1向最知名的聊天提问
问: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 |
‘24’ |
\b |
字边界 |
答案4
嗯,您只依赖于可能具有值 24 的一个字段。这似乎是一个糟糕的设计 – 有很多工具可以从这样的文件中提取第一列和第三列,例如cut
,用于进一步分析。
不过,老实说:这是处理表格数字数据的工具的工作,而不是像sed
or cut
or 这样的字符串引擎的工作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
即可。