Reputation: 305
File1:
1|footbal|play1
2|cricket|play2
3|tennis|play3
5|golf|play5
File2:
1|footbal|play1
2|cricket|play2
3|tennis1|play3
4|soccer|play4
5|golf|play6
Output File:
4|soccer|play4
5|golf|play6
I am comparing all columns of file1 and file2, but I need to ignore the second column while comparing.
awk 'NR==FNR {exclude[$0];next} !($0 in exclude)' file1 file2 > file3
Upvotes: 0
Views: 1436
Reputation: 133438
EDIT2(Generic solution): To nullify more than 1 column(s) in both the Input_file(s) could try following. I have made variables for it so you need not to hard code fields which you want to nullify in your code. One should mention all field numbers separated with ,
in -v file1_ignore
and file2_ignore
variables of this awk program.
awk -v file1_ignore="2,3" -v file2_ignore="2,3" '
BEGIN{
FS=OFS="|"
num1=split(file1_ignore,array1,",")
num2=split(file2_ignore,array2,",")
}
FNR==NR{
for(i=1;i<=num1;i++){
$array1[i]=""
}
a[$0]
next
}
{
val=$0
for(i=1;i<=num2;i++){
$array2[i]=""
}
}
!($0 in a){
print val
val=""
}
' file1 file2
Explanation: Adding a detailed explanation for above code.
awk -v file1_ignore="2,3" -v file2_ignore="2,3" ' ##Starting awk program from here and setting variables named file1_ignore(which will be used to ignoring fields in Input_file1), file2_ignore(which will be used to ignoring fields in Input_file2).
BEGIN{ ##Starting BEGIN section from here.
FS=OFS="|" ##Setting field seaprator and output field separator as | here.
num1=split(file1_ignore,array1,",") ##Spitting file1_ignore variable to array1 here with separator as , here.
num2=split(file2_ignore,array2,",") ##Spitting file1_ignore variable to array2 here with separator as , here.
} ##Closing BEGIN BLOCK for this code here.
FNR==NR{ ##Checking condition which will be TRUE for first Input_file Input_file1 here.
for(i=1;i<=num1;i++){ ##Starting for loop to run till variable num1 here.
$array1[i]="" ##Nullifying field(which will be get by value of array1).
} ##Closing above for loop BLOCK here.
a[$0] ##Creating an array with index of current line.
next ##next will skip all further statements from here.
} ##Closing BLOCK for FNR==NR condition here.
{
val=$0 ##Creating a variable val whose value is current line.
for(i=1;i<=num2;i++){ ##Starting for loop to run till variable num2 here.
$array2[i]="" ##Nullifying field(which will be get by value of array2).
} ##Closing above for loop BLOCK here.
}
!($0 in a){ ##Checking condition if current line is NOT present in array a then run futher statements.
print val ##Printing variable val here.
val="" ##Nullify variable val here.
}
' file1 file2 ##Mentioning Input_file(s) name here.
EDIT1: To ignore multiple and different columns in both the files try following, I have taken example of same column number 2 to be nullified in both files you could keep it as per your need too.
awk -v file1_ignore="2" -v file2_ignore="2" '
BEGIN{
FS=OFS="|"
}
FNR==NR{
$file1_ignore=""
a[$0]
next
}
{
val=$0
$file2_ignore=""
}
!($0 in a){
print val
val=""
}
' file1 file2
Could you please try following.
awk 'BEGIN{FS="|"}FNR==NR{a[$1,$3];next} !(($1,$3) in a)' file1 file2
Upvotes: 2
Reputation: 37394
To ignore:
$ awk -F\| '
NR==FNR { # first file
$2="" # empty the unwanted fields, chain them: $2=$3=...$n=""
a[$0] # hash on $0
next # next record
}
{ # second file
b=$0 # backup the record to b
$2="" # empty the same field
if(!($0 in a)) # refer
print b # output the backup
}' file file2
Output:
4|soccer|play4
5|golf|play6
This of course makes sense only if NF >> amount of fields to null. In other case use the other solutions.
Upvotes: 4
Reputation: 10865
The comma ,
operator is handy here to treat the fields individually. If you just want the first and third fields you can use the same pattern you already have:
$ awk -F\| 'NR==FNR {exclude[$1,$3];next} !(($1,$3) in exclude)' file1 file2
4|soccer|play4
5|golf|play6
Upvotes: 2