Может быть что-то вроде этого:
egrep '^\s+[0-9]+\s+v\|([0-9a-zA-Z-]+)$' files* | sed -e 's/v|//g'
$ awk -v OFS='\t' -f script.awk file
ID1 76 266
ID2 3762 62 1541
Где script.awk
это
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }
Все блоки будут выполняться для каждой строки ввода из файла.
Первый блок выводит идентификатор.
Второй блок перебирает поля, как вы описали, и выводит данные, разделенныеOFS
(разделителем выходных полей, установленным на вкладке в командной строке ).
Последний блок просто выводит разделитель записей RS
, который по умолчанию является новой строкой.
Как вариант,
BEGIN { OFS = "\t" }
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }
, чтобы избавиться от необходимости -v OFS='\t'
.
Как «один -лайнер»:
$ awk 'BEGIN { OFS = "\t" }
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }' file
Для расширенной задачи:
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d%s%d", OFS, $(i-1), OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s%d%s%s", OFS, $NF, OFS, RS) }
Это создаст следующее прямо из исходного файла:
ID1 234 76 392 266 470
ID2 176 3762 869 62 347 1541 231