Как игнорировать указанный столбец c при сравнении двух файлов с использованием awk - PullRequest
0 голосов
/ 06 января 2020

Файл1:

1|footbal|play1
2|cricket|play2
3|tennis|play3
5|golf|play5

Файл2:

1|footbal|play1
2|cricket|play2
3|tennis1|play3
4|soccer|play4
5|golf|play6

Выходной файл:

4|soccer|play4
5|golf|play6

Я сравниваю все столбцы файла1 и файла2, но мне нужно игнорировать второй столбец при сравнении.

awk 'NR==FNR {exclude[$0];next} !($0 in exclude)' file1 file2 > file3

Ответы [ 3 ]

4 голосов
/ 06 января 2020

Игнорировать:

$ 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

Вывод:

4|soccer|play4
5|golf|play6

Это, конечно, имеет смысл, только если NF >> количество полей, равное нулю. В другом случае используйте другие решения.

2 голосов
/ 06 января 2020

EDIT2 (Generi c решение): Чтобы обнулить более 1 столбца в обоих файлах Input_file, можно попробовать выполнить следующее. Я сделал для него переменные, поэтому вам не нужно жестко кодировать поля, которые вы хотите обнулить в своем коде. Следует упомянуть все номера полей, разделенные , в -v file1_ignore и file2_ignore переменных этой awk-программы.

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

Объяснение: Добавление подробное объяснение приведенного выше кода.

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: Чтобы игнорировать несколько и разные столбцы в обоих файлах, попробуйте следующее, у меня есть Взяв пример того же столбца № 2, который нужно обнулить в обоих файлах, вы можете сохранить его в соответствии с вашими потребностями.

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


Не могли бы вы попробовать следующее.

awk 'BEGIN{FS="|"}FNR==NR{a[$1,$3];next} !(($1,$3) in a)' file1 file2
2 голосов
/ 06 января 2020

Оператор запятой , удобен для индивидуальной обработки полей. Если вам просто нужны первое и третье поля, вы можете использовать тот же шаблон, который у вас уже есть:

$ awk -F\| 'NR==FNR {exclude[$1,$3];next} !(($1,$3) in exclude)' file1 file2
4|soccer|play4
5|golf|play6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...