具有至少一个匹配值和至少一个不匹配值的Grep

具有至少一个匹配值和至少一个不匹配值的Grep,grep,Grep,我有一些文件,我希望grep返回行,其中至少有一个字符串位置:“Engineer”和至少一个位置不等于“Engineer”的字符串 因此,在下面的文件中,应该只返回第一行: Position:"Engineer" Name:"Jes" Position:"Accountant" Name:"Criss" Position:"Engineer" Name:"Eva" Posit

我有一些文件,我希望grep返回行,其中至少有一个字符串位置:“Engineer”和至少一个位置不等于“Engineer”的字符串 因此,在下面的文件中,应该只返回第一行:

Position:"Engineer" Name:"Jes" Position:"Accountant" Name:"Criss" 
Position:"Engineer" Name:"Eva" Position:"Engineer" Name:"Adam"
我可以写这样的东西

grep 'Position:"Engineer"' filename | grep 'Position:"Accountant"'
grep 'Position:"Engineer"' filename | grep -v 'Position:"Engineer"'
这很好(我只得到第一行),但问题是我不知道所有可能的值是什么,所以grep需要像这样的通用值

grep 'Position:"Engineer"' filename | grep 'Position:"Accountant"'
grep 'Position:"Engineer"' filename | grep -v 'Position:"Engineer"'
但这不会返回任何结果(因为两个grep相互矛盾)

你知道怎么做吗?

这行代码:

grep "^Position:\"Engineer\"" filename | grep -v " Position:\"Engineer\"" 

第一个带“$”的表达式只捕捉行开头的位置,第二个带“空格”的表达式删除第二个“Position”表达式。

如果允许,可以使用
awk
避免管道和附加子shell,例如

awk '
    $1~/Engineer/ {if ($3~/Engineer/) next; print}
    $3~/Engineer/ {if ($1~/Engineer/) next; print}
' file
上面只检查第一个字段是否包含
Engineer
,如果是,则检查字段3是否也包含
Engineer
,如果是,则跳过记录,如果不是,则打印记录。第二条规则,只是交换测试的顺序。测试结果是
Engineer
只能出现在其中一个字段中(第一个或第三个,但不能同时出现在两个字段中)

示例使用/输出

使用
文件中的示例输入
,您将拥有:

$awk'
$1~/Engineer/{if$3~/Engineer/)next;print}
$3~/Engineer/{if($1~/Engineer/)next;print}
"档案"
职位:“工程师”姓名:“Jes”职位:“会计”姓名:“CRIS”

管道中有两个
grep
s:

grep -F 'Position:"Engineer"' file | grep -Ev '(Position:"[^"]*").*\1'
或者,也许更有力

grep -F 'Position:"Engineer"' file | grep -v 'Position:"Engineer".*Position:"Engineer"'
一般情况下,如果要打印具有唯一
位置
字段的行

grep -Ev '(Position:"[^"]*").*\1' file

应该执行此操作,假设所有行都具有指定的格式。当行中有两个以上的
Position
字段时,这也会起作用。

在匹配后使用负前瞻排除模式

grep 'Position:"Engineer"' | grep -P 'Position:"(?!Engineer)'

grep-e'.*Engineer.*accountary.*-e'.*accountary.*Engineer.*'file.txt
谢谢,我已经纠正了这个错误!但当职位互换时,也就是说,非工程师职位先到,工程师职位后到时,这将不起作用。是的,同意,但关于这个案例还有其他信息。