отдельные поля на основе содержимого первого столбца, сопоставления во втором столбце и вычитания в значениях четвертого столбца в awk - PullRequest
2 голосов
/ 08 февраля 2020

Мой входной файл имеет вид:

a10 otu1 xx 44
b24 otu2 xxx 52
x35 otu3 xy 11
x45 otu3 zz 22
z452 Otu5 rr 78
control1 otu1 w 4
control2 otu2 ee 30
control3 otu3 tt 20
control4 otu4 yy 10

Сначала я хочу отделить элемент управления от других в столбце 1, а затем сопоставить значения элемента управления второго столбца со вторым столбцом другого элемента. Если во втором столбце найдено совпадение, я хочу вычесть соответствующие значения в четвертом столбце.

Выходной файл будет:

a10 otu1 xx 40
b24 otu2 xxx 22
x35 otu3 xy -9
x45 otu4 zz 12
z452 Otu5 rr 78

Теперь, чтобы сопоставить второй столбец и вычесть значения в Четвёртый столбец, который я использую:

awk 'NR==FNR {a[$2]=$2 in a?a[$2]-$4:$4; next} !b[$2]++ {print $1,$2,$3,a[$2]}' inputfile.txt{,}

Как я могу передать отдельную информацию о поле (элемент управления против других) в сценарии?

Ответы [ 3 ]

2 голосов
/ 08 февраля 2020

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

awk '
!/^control/{
  a[++count1]=$NF
  b[count1]=$1 OFS $2 OFS $3
  next
}
{
  c[++count2]=$NF
}
END{
  for(i=1;i<=count1;i++){
    print b[i],a[i]-c[i]
  }
}
'   Input_file


Более универсальный c решение: В случае, если вы не хотите жестко закодировать значения полей в первом массиве a, и у вас есть более 4 полей в первом файле, затем попробуйте выполнить следующее.

awk '
!/^control/{
  a[++count1]=$NF
  $NF=""
  sub(/ +$/,"")
  b[count1]=$0
  next
}
{
  c[++count2]=$NF
}
END{
  for(i=1;i<=count1;i++){
    print b[i],a[i]-c[i]
  }
}
' Input_file
1 голос
/ 08 февраля 2020

Вот еще один вариант:

/^control/ {
  a[$2]=a[$2]-$4
  next
}

{
  a[$2]=a[$2]+$4
  b[$2]=$1 OFS $2 OFS $3
}

END {
  for(i in b) print b[i] OFS a[i]
}

Это вычитает любые значения в строках control, добавляет любые значения в другие строки, сохраняя их в массиве a[]. Он поддерживает массив содержимого строки, b[].

. Храня содержимое в массиве, можно создать несколько строк данных или управляющих строк, влияющих на значение, и они могут отображаться в любом порядке на входе. (поскольку 44 - 40 - это то же самое, что и -40 + 44).

Обратите внимание, что, поскольку наш END для l oop проходит через массив, выход не обязательно будет в том же порядке, что и ввод.

1 голос
/ 08 февраля 2020
$ cat tst.awk
NR==FNR {
    if ( /^control/ ) {
        control[$2] = $NF
    }
    next
}
!/^control/ {
    $NF = $NF - control[$2]
    print
}

$ awk -f tst.awk file file
a10 otu1 xx 40
b24 otu2 xxx 22
x35 otu3 xy -9
x45 otu3 zz 2
z452 Otu5 rr 78
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...