Bash 不等于带awk的运算符

Bash 不等于带awk的运算符,bash,if-statement,awk,Bash,If Statement,Awk,我不确定我做错了什么,但我肯定在我的awk命令中犯了一些错误 我有两个文件,fileA包含名称 菲拉 FileB包含具有名称的其他数据 Abhi 23 Pk DaDa 43 Gk Roma 33 Kk PkPk 22 Aa 现在,我试图打印fileA中缺少的所有名称的详细信息 for i in `cat FileA` ; do cat FileB | awk '{ if ($1!='$i') print $0_}'>> Result; done 我得到的是 Abhi

我不确定我做错了什么,但我肯定在我的awk命令中犯了一些错误

我有两个文件,fileA包含名称

菲拉

FileB包含具有名称的其他数据

Abhi 23  Pk
DaDa 43  Gk
Roma 33  Kk
PkPk 22  Aa
现在,我试图打印fileA中缺少的所有名称的详细信息

for i in `cat FileA` ; do cat FileB | awk '{ if ($1!='$i') print $0_}'>> Result; done
我得到的是

Abhi    23  Pk
DaDa    43  Gk
Roma    33  Kk
PkPk    22  Aa
Abhi    23  Pk
DaDa    43  Gk
Roma    33  Kk
PkPk    22  Aa
Abhi    23  Pk
DaDa    43  Gk
期望输出

DaDa 43  Gk
PkPk 22  Aa
有人能帮我找出错误吗

谢谢你,你只需要grep:

这将使用fileA从中获取模式。然后,-v反转匹配

很好地解释了为什么没有正确匹配行。现在,让我们看看您的解决方案需要改进的地方:

您的代码是:

for i in `cat FileA`
do
    cat FileB | awk '{ if ($1!='$i') print $0_}'>> Result
done
解释得很好。因此,您需要说一些类似于中所述的内容:

此外,重定向可以在“完成”的末尾完成,因此您可以使用更清晰的命令:

while IFS= read -r line
do
    awk '{ if ($1!='$i') print $0_}' FileB
done < fileA >> Result
也可以说:

awk 'condition' file
因为{print$0}是条件计算为true时要执行的默认操作

另外,要让awk使用bash变量,您需要使用awk-v var=$shell\u var,然后在内部使用var-

总之,你应该这样说:

while IFS= read -r line
do
    awk -v var="$line" '$1 != var' FileB
done < fileA >> Result
但是,由于您在文件中循环了很多次,因此它将打印很多次。这就是为什么您必须一直使用grep-vf fileA fileB来回答这个问题。

为此,您只需要grep:

这将使用fileA从中获取模式。然后,-v反转匹配

很好地解释了为什么没有正确匹配行。现在,让我们看看您的解决方案需要改进的地方:

您的代码是:

for i in `cat FileA`
do
    cat FileB | awk '{ if ($1!='$i') print $0_}'>> Result
done
解释得很好。因此,您需要说一些类似于中所述的内容:

此外,重定向可以在“完成”的末尾完成,因此您可以使用更清晰的命令:

while IFS= read -r line
do
    awk '{ if ($1!='$i') print $0_}' FileB
done < fileA >> Result
也可以说:

awk 'condition' file
因为{print$0}是条件计算为true时要执行的默认操作

另外,要让awk使用bash变量,您需要使用awk-v var=$shell\u var,然后在内部使用var-

总之,你应该这样说:

while IFS= read -r line
do
    awk -v var="$line" '$1 != var' FileB
done < fileA >> Result

但是,由于您在文件中循环了很多次,因此它将打印很多次。这就是为什么您必须一直使用grep-vf fileA fileB来回答这个问题。

问题是,当您要与字符串进行比较时,该字符串必须位于引号之间,否则,它会假定该字符串是一个变量名

例如:

awk '{ if ($1!=name) print $0_}'
在本例中,awk将假定name是一个变量,它将是空的,因为没有给它赋值,因此,将$1与空字符串进行比较

awk '{ if ($1!="name") print $0_}'
在本例中,awk将把$1与字符串名进行比较

因此,正确的代码是:

for i in `cat FileA` ; do cat FileB | awk -v var="$i" '{ if ($1!=var) print $0_}'>> Result; done
这也会起作用,尽管我认为前面的方法更清楚:

for i in `cat FileA` ; do cat FileB | awk '{ if ($1!="'$i'") print $0_}'>> Result; done

编辑:检查答案以了解解决方案中更好的方法问题在于,当您要与字符串进行比较时,该字符串必须位于引号之间,否则,它会假定该字符串是变量名

例如:

awk '{ if ($1!=name) print $0_}'
在本例中,awk将假定name是一个变量,它将是空的,因为没有给它赋值,因此,将$1与空字符串进行比较

awk '{ if ($1!="name") print $0_}'
在本例中,awk将把$1与字符串名进行比较

因此,正确的代码是:

for i in `cat FileA` ; do cat FileB | awk -v var="$i" '{ if ($1!=var) print $0_}'>> Result; done
这也会起作用,尽管我认为前面的方法更清楚:

for i in `cat FileA` ; do cat FileB | awk '{ if ($1!="'$i'") print $0_}'>> Result; done

编辑:检查答案以获得解决方案中更好的方法

在将代码更新为while IFS=read-r i后,如有必要,更新您的问题;do awk-vi=$i'$1!=i{打印$0}'文件b;完成结果。看。给像我这样的人注意:当你有在awk表达式中,使用单引号“!=”而不是双引号!=。在将代码更新为while IFS=read-ri之后,如有必要,更新您的问题;do awk-vi=$i'$1!=i{打印$0}'文件b;完成结果。看。给像我这样的人注意:当你有在awk表达式中,使用单引号“!=”而不是双引号!=。不,因为我在cat文件中不是一个好建议。也不是通过这种方式循环文件。我同意这不是一个好建议,但他想知道awk的问题是什么。我只限于回答这个问题。是的,我同意这一点,并且+1是一个很好的解释。然而,指出一个更好的方法会使你的答案更加闪亮:谢谢,我会在我的答案中提到你,因为你已经解释了一个更好的方法否,因为我在cat文件中不是一个好的建议。也不是通过这种方式循环文件。我同意这不是一个好建议,但他想知道awk的问题是什么。我只限于回答这个问题。是的,我同意这一点,并且+1是一个很好的解释。然而,指出一个更好的方法会让你的答案更加闪亮:谢谢,我会在我的答案中提到你,因为你已经解释了一个更好的方法approach@Angelo请看详细的解释。@Angelo请看详细的解释。