bash 不等于 awk 的运算符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39413335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:25:10  来源:igfitidea点击:

not equal to operator with awk

bashif-statementawk

提问by Angelo

I am not sure what wrong I am doing but I am certainly making some mistake with my awk command.

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

I have two files, fileA contains names

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

FileA

文件A

Abhi
Roma
GiGi
KaKa

FileB contains other data with names

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

Abhi 23  Pk
DaDa 43  Gk
Roma 33  Kk
PkPk 22  Aa

Now, I trying to print the details of all the names that are absent in fileA.

现在,我尝试打印 fileA 中不存在的所有名称的详细信息。

for i in `cat FileA` ; do cat FileB | awk '{ if (!='$i') print 
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
_}'>> Result; done

What I get is

我得到的是

DaDa 43  Gk
PkPk 22  Aa

Desired output

期望输出

$ grep -vf fileA fileB
DaDa 43  Gk
PkPk 22  Aa

Could anyone help me in finding out the error.

谁能帮我找出错误。

Thank you

谢谢

回答by fedorqui 'SO stop harming'

For this you just need grep:

为此,您只需要grep

for i in `cat FileA`
do
    cat FileB | awk '{ if (!='$i') print 
while IFS= read -r line
do
    cat FileB | awk '{ if (!='$i') print 
while IFS= read -r line
do
    awk '{ if (!='$i') print 
while IFS= read -r line
do
    awk '{ if (!='$i') print 
awk '{if (condition) print 
awk 'condition' file
}' file
_}' FileB done < fileA >> Result
_}' FileB >> Result done < fileA
_}'>> Result done < fileA
_}'>> Result done

This uses fileAto obtain the patterns from. Then, -vinverts the match.

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

AwkManaddresses very well why you are not matching lines properly. Now, let's see where your solution needs polishing:

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

Your code is:

你的代码是:

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

Why you don't read lines with "for"explains it well. So you would need to say something like the described in Read a file line by line assigning the value to a variable:

为什么你不阅读带有“for”的行很好地解释了这一点。因此,您需要说一些类似于Read a file line by line 将值分配给变量中描述的内容

awk '{ if (!=name) print 
awk '{ if (!="name") print 
for i in `cat FileA` ; do cat FileB | awk -v var="$i" '{ if (!=var) print 
for i in `cat FileA` ; do cat FileB | awk '{ if (!="'$i'") print ##代码##_}'>> Result; done
_}'>> Result; done
_}'
_}'

Then, you are saying cat file | awk '...'. For this, awk '...' fileis enough:

那么,你是说cat file | awk '...'。为此,awk '...' file就足够了:

##代码##

Also, the redirection could be done at the end of the done, so you have a clearer command:

此外,重定向可以在 的末尾完成done,因此您有一个更清晰的命令:

##代码##

Calling awkso many times is not useful and you can use the FNR==NRtrickto process two files together.

调用awk这么多次是没有用的,你可以使用这个FNR==NR技巧一起处理两个文件。

Let's now enter in awk. Here you want to use some kind of variable to compare results. However, $iis nothing to awk.

现在让我们进入awk。在这里您想使用某种变量来比较结果。不过,$i也没什么awk

Also, when you have a sentence like:

另外,当你有这样的句子时:

##代码##

It is the same to say:

说是一样的:

##代码##

Because {print $0}is the default action to perform when a condition evaluates to true.

因为{print $0}是当条件评估为真时要执行的默认操作。

Also, to let awkuse a bash variable you need to use awk -v var="$shell_var"and then use varinternally-

此外,要awk使用您需要使用的 bash 变量awk -v var="$shell_var",然后在var内部使用 -

All together, you should say something like:

总之,你应该这样说:

##代码##

But since you are looping through the file many times, it will print the lines many, many times. That's why you have to go all the way up to this answer and use grep -vf fileA fileB.

但是由于您多次循环访问该文件,它会多次打印这些行。这就是为什么你必须一直走到这个答案并使用grep -vf fileA fileB.

回答by AwkMan

The problem is that when you want to compare with a string, that string must be between quotes, otherwise, it assumes that the string is a variable name.

问题是当你想与一个字符串进行比较时,该字符串必须在引号之间,否则,它假定该字符串是一个变量名。

For example:

例如:

##代码##

In this case, awk will assume that "name" is a variable, which will be empty, as no value has been assigned to it, and hence, compare $1 with an empty string.

在这种情况下,awk 将假定 "name" 是一个变量,该变量将为空,因为尚未为其分配值,因此将 $1 与空字符串进行比较。

##代码##

In this case, awk will compare $1 with the string "name".

在这种情况下,awk 会将 $1 与字符串“name”进行比较。

Therefore, the correct code for you is:

因此,您的正确代码是:

##代码##

This will also work, though I think it is clearer in the previous way:

这也可以,但我认为以前的方式更清楚:

##代码##

EDIT: Check fedorquianswer for a better approach in the solution

编辑:检查fedorquianswer 以获得更好的解决方案