2016-09-09 2 views
1

내가 뭘 잘못하고 있는지 확실하지 않지만 awk 명령으로 실수를하고있다. 나는 두 개의 파일이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 

입니다.

방금 ​​ grep 필요 당신이 들어

+0

코드를'IFS = read -ri while '으로 업데이트 한 후, 필요한 경우 질문을 업데이트하십시오. awk -v i = "$ i" '$ 1! = i {print $ 0}'FileB; 완료 < FileA > 결과'. ([배쉬 FAQ 001] (http://mywiki.wooledge.org/BashFAQ/001) 참조.) – chepner

답변

3

감사합니다

$ 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의 끝에서 수행 할 수 있습니다 :

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

awk 너무 여러 번 호출입니다 유용하지 FNR==NR trick을 사용하여 두 파일을 함께 처리 할 수 ​​있습니다.

이제 awk에 입력 해 보겠습니다. 여기에서는 결과를 비교하기 위해 일종의 변수를 사용하려고합니다. 그러나 $iawk이 아닙니다.당신은 같은 문장이있을 때 또한

:

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

을 그것은 말할 동일합니다 {print $0}는 조건이 true로 평가 때 수행 할 기본 동작은

awk 'condition' file 

때문입니다. awk가 모두 함께 var은 내부적

을 사용하면 다음 awk -v var="$shell_var"을 사용할 필요가 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 

편집 : : A의 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