Сравните два файла и проигнорируйте совпадающее содержимое и добавьте несопоставимое содержимого из файла 2 в файл 1 в определенном формате

Вот сценарий awk. Просто измените число 5 , чтобы иметь другие группы.

awk '
NR==1{
 previous = $1
 for(i = 1;i<=NF+1;i++)
  if($i!=previous){
    col[++numcol] = i
    previous = $i
  }
}
{ j = 1; start = 1
  for(i = 1;i<NF;i++){
   printf "%s",$i
   if(i==col[j]-1){printf "  "; start = col[j++]}
   else if((i-start+1)%5==0)printf "  "
  }
  printf "%s\n",$NF
}'

Первая часть просто обрабатывает строку 1 и собирает в массиве col начальный столбец для каждого набора одинаковых чисел. Вторая часть печатает каждое поле без разделения, за исключением столбца 5 от начального столбца или в конце последовательности.

0
21.01.2019, 17:35
3 ответа

Попробуйте это:

awk '
     FNR==NR {seen[$2,$3]=1; print $0 }
     FNR!=NR && !seen[$1,$2] { print 2019,$0,0 }
' file1 file2

Пояснение:

  • FNR==NR {... }Запускайте команды в скобках только для первого файла.
  • seen[$2,$3]=1, установить массив seenс ключами $2,$3 в 1.
  • print $0напечатать всю строку.
  • FNR!=NR && !seen[$1,$2] {... }Выполнять команды в скобках только если не первый файл и если поля $1,$2 не являются ключами в массиве seen.
  • print 2019,$0,0напечатать строку, окруженную новыми столбцами 2019 и 0.

Добавьте | column -tдля выровненного вывода.

Выход:

$ awk 'FNR==NR{seen[$2,$3]++; print $0} FNR!=NR && !seen[$1,$2]{print 2019,$0,0}' file1 file2 | column -t
2019  ABCD  1  10
2019  DEF   2  11
2019  GHI   1  20
2019  jkl   2  25
2019  jkl   1  0
2019  mnop  2  0
2019  qrst  1  0
3
28.01.2020, 02:23

Это должно работать:

$ awk 'NR==FNR{a[$2$3]++; print; next}!($1$2 in a){print "2019",$0,"0"}' file1 file2 
2019  ABCD 1 10
2019  DEF  2 11
2019  GHI  1 20
2019  jkl  2 25
2019 jkl  1 0
2019 mnop  2 0
2019 qrst  1 0

Пояснение

  • NR==FNR:NR — номер текущей строки, FNR — номер строки текущего файла. Они будут идентичны только во время чтения первого файла.
  • {a[$2$3]++; print; next}:при чтении первого файла(file1)использовать 2-е и 3-е поля в качестве ключа для ассоциативного массива a. Это просто используется, чтобы отслеживать, какие из них мы уже видели. Затем распечатайте эту строку и перейдите к следующей. Это nextгарантирует, что остальная часть скрипта будет выполняться только для второго файла, когда NRне совпадает с FNR.
  • !($1$2 in a):если первое и второе поля этой строки не используются в качестве ключей в массиве a(, это означает, что 1-е и 2-е поля объединены, поэтому, если 1-е это fooи второе bar, $1$2будетfoobar).
  • {print "2019",$0,"0"}:напечатать 2019, текущую строку из file2и 0.
0
28.01.2020, 02:23

Вот совсем другой способ сделать это:

mkns() {
    # make keys from parameters $2 and $3 for joining, then sort the keys
    sort -k 1b,1 <(awk "{print \$$2\$$3, \$0}" $1)
}

Затем запустите

join -j 1 -v 2 <(mkns file1 2 3) <(mkns file2 1 2) | awk '{print 2019, $2, $3, 0}' | cat file1 - | column -t

Это не так коротко, как чисто awkрешения от RoVo и Tendon, но я думаю, что это интересное решение, потому что joinможно использовать для «отфильтровывания» нужных вам строк.

0
28.01.2020, 02:23

Теги

Похожие вопросы