linux 如何使用grep命令显示文件最后一个字段中大于100k但小于140k的条目

pgccezyw  于 2022-12-18  发布在  Linux
关注(0)|答案(4)|浏览(165)

我需要创建一个grep命令来从雇员文件中选择条目。
员工列表文件将工资作为文件中每行的最后一个字段。
如何使用grep只选择薪资大于100000且小于140000的员工?
这就是我目前所拥有的,但是我不知道如何防止列表中的100000个结果显示在grep结果中。

grep "[1][0-3]....$" emp.lst

下面是我从grep得到的结果...

$ grep "[1][0-3]....$" emp.lst
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :100000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :130000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :120000

下面是emp.lst的整个文件的cat ...

2233    :a.k. shukla         :g.m.      :sales          :12/12/52  :6000
9876    :jai sharma          :director  :production     :03/12/50  :7000
5678    :sumit chakrobarty   :d.g.m     :marketing      :04/19/43  :6000
2365    :barun sengupta      :director  :personnel      :05/11/47  :7800
5423    :n.k. gupta:chairman :admin                     :08/30/56  :5400
1006    :chanchal sanghvi    :director  :sales          :09/03/38  :6700
6213    :karuna ganguly      :g.m.      :accounts       :06/05/62  :6300
1265    :s.n. dasgupta       :manager   :sales          :09/12/63  :5600
4290    :jayant Chodhury     :executive :production     :09/07/50  :6000
2476    :anil aggarwal       :manager   :sales          :05/01/59  :5000
6521    :lalit chowdury      :director  :marketing:     :09/26/45   :8200
3212    :shyam saksena       :d.g.m     :accounts       :12/12/55  :6000
3564    :sudhir Agarwal      :executive :personnel      :07/06/47  :8000
2345    :j.b. saxena         :g.m.      :marketing      :03/12/45  :140000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :100000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :150500
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :130000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :120000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :190000
kkih6yb8

kkih6yb81#

虽然可以尝试用regex进行数值比较,但我建议不要这样做,像awk这样的东西似乎更适合手头的任务。

awk '{if( gensub( /:/, "",1, $NF) > 100000 && gensub( /:/, "",1, $NF) < 140000){print}}' emp.lst
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :130000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :120000

由于格式似乎是固定宽度的,所以我将:替换为空,以使每行最后一个字段的数字比较成为可能。

9lowa7mx

9lowa7mx2#

你的指导老师已经偏离了轨道,因为这对grep来说是一个完全不合适的任务,即使是作为一个练习,当然除非她试图教你this quote的含义:

Some people, when confronted with a problem, think
“I know, I'll use regular expressions.”  Now they have two problems.

在任何情况下,在UNIX中执行此操作的正确方法是:

$ awk -F: '100000<$NF && $NF<140000' file
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :130000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :120000
xzv2uavs

xzv2uavs3#

简单的答案是使用[1-3][0-3]character-class 作为第二个数字,并将[0-3]替代项限制为末尾的[1-9]类。

$ grep '1[1-3][0-9][0-9][0-9][0-9]$\|1[0-3][0-9][0-9][0-9][1-9]$' file
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :130000
0110    :v.k. agrawal        :g.m.      :marketing      :12/31/40  :120000

其中,1[1-3][0-9][0-9][0-9][0-9]$捕获110000-1399991[0-3][0-9][0-9][0-9][1-9]确保忽略小于100001的值。
要处理所有值,包括示例中未显示的值,可以扩展表达式以检查每个值,并使用[:]锚开头,例如

grep '[:]1[1-3][0-9][0-9][0-9][0-9]$\|[:]1[0-3][0-9][0-9][0-9][1-9]\|[:]1[0-3][1-9][0-9][0-9][0-9]\|[:]1[0-3][0-9][1-9][0-9][0-9]$\|[:]1[0-3][0-9][0-9][1-9][0-9]' file

如果您还有其他问题,请告诉我。

kiayqfof

kiayqfof4#

如果您可以使用perl兼容的正则表达式(grep -P),则可以执行以下操作:

grep -P ':(?=1[0-3]\d{4}$)(?!100000$)' emp.lst

: - required so that we will have a main expression and not only lookaheads
(?=1[0-3]\d{4}$) - positive lookahead that will match all the numbers less than 140000
(?!100000$) - negative lookahead that will discard 100000 matches

这是因为lookaheads不消耗字符,负的字符将重新检查与正的字符匹配的内容。
如果不能使用grep -P,可以使用管道:

grep "[1][0-3]....$" emp.lst | grep -v ':100000$'

grep -v不返回匹配项,因此它将过滤所有包含100000的行。

相关问题