2016-09-09 18 views
1

私は何が間違っているのかよく分かりませんが、私は確かにawkコマンドで間違いを犯しています。私は2つのファイルを持っているawkの演算子と等しくない

は、FILEAは名前

FILEA

Abhi 
Roma 
GiGi 
KaKa 

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 

です。

はあなたにこのため

+0

コードを 'IFS = read -ri while 'に更新した後、必要に応じて質問を更新してください。 awk -v i = "$ i" '$ 1!= i {print $ 0}'を実行します。完了< FileA >結果 '。 ([Bash FAQ 001](http://mywiki.wooledge.org/BashFAQ/001)を参照してください。) – chepner

答えて

3

ありがとうあなただけgrepが必要になります。

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

これからパターンを取得するためにfileAを使用しています。その後、-vがマッチを逆転させます。

AwkManなぜあなたは正しく行を一致させていないのですか。さて、あなたのソリューションは、研磨必要がある場合を見てみましょう:

あなたのコードは次のとおりです。

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

Why you don't read lines with "for"はそれをよく説明しています。だから、Read a file line by line assigning the value to a variableで説明したような何かを言う必要があるでしょう:

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

その後、あなたはcat file | awk '...'を言っています。このため、awk '...' fileは十分です:あなたが明確コマンドを持っているので、

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

はまた、リダイレクトは、doneの終わりに行うことができる:awk何度も呼び出す

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

は有用ではありませんFNR==NR trickを使用して2つのファイルを一緒に処理することができます。

今度はawkと入力してください。ここでは、ある種類の変数を使用して結果を比較したいとします。ただし、$iawkにはありません。また

、あなたのような文がある場合:

awk '{if (condition) print $0}' file 

をそれは言って同じです:

awk 'condition' file 

{print $0}は、条件がtrueと評価されたときに実行するデフォルトのアクションですので。

また、awkあなたはawk -v var="$shell_var"を使用して、すべて一緒にvar

internally-を使用する必要がbashの変数を使用できるように、あなたのような何かを言う必要があります。

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

をしかし、あなたはをループしているので、ファイルは何度も、何度も何度も行を印刷します。だからこそあなたはこの答えに至るまで進み、grep -vf fileA fileBを使用しなければなりません。

+0

私の知らせを聞かせてください。 – Angelo

+0

@Angelo詳細な説明を参照してください。 – fedorqui

2

問題は、文字列と比較する場合は、その文字列を引用符で囲む必要があります。そうでない場合は、文字列が変数名であることが前提です。例えば

:この場合

awk '{ if ($1!=name) print $0_}' 

、AWKは値がそれに割り当てられていないように、「名前」が空になり変数であると仮定し、したがって、で$ 1比較します空の文字列。

awk '{ if ($1!="name") print $0_}' 

この場合、awkは$ 1を文字列 "name"と比較します。

したがって、あなたのための正しいコードは次のとおりです。

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

EDIT:用fedorqui答えをチェック

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

これも、私はそれが以前のように明確だと思いますが、動作しますソリューションでのより良いアプローチ

+1

いいえ、 'cat file'のiは良いアドバイスではありません。この方法ではファイルをループしません。私の答えを見てください。 – fedorqui

+0

私はそれが良いアドバイスではないことに同意しますが、彼はawkの問題が何かを知りたがっていました。私はその問題に答えることを制限しました。 – AwkMan

+0

はい、私はそれに同意し、+1を書いて良い説明をします。しかし、より良いアプローチを示すことで、あなたの答えがさらに輝くようになります:) – fedorqui

関連する問題