Вы можете использовать perl для выполнения математических операций в регулярном выражении:
perl -pe 's/viewBox="(\d+) (\d+) (\d+) (\d+)"/"viewBox=\"".($1*10)." ".($2*10)." ".($3*10)." ".($4*10)."\""/eg' <input file>
Его можно было бы немного почистить, сделав его полным сценарием, а не одной строкой. В этот момент я, вероятно, вытащу математику в регулярном выражении и заменю ее циклом по значениям в viewBox.
awk 'BEGIN{ OFS="\t" } {
nrf=split($0, tmp); s1=s2=0;
for(i=1; i<=nrf; i++){
printf "%s", (tmp[i] ~/DP4=/ &&++s1? (s2?OFS:"") tmp[i]:
(tmp[i]=="MODERATE" &&++s2? (s1?OFS:"") tmp[i-1] OFS tmp[i] OFS tmp[i+1]:"") );
}; print "";
}' infile
мы использовали функцию split (), чтобы каждый раз разбивать текущую строку обработки на временный массив с именем tmp по умолчанию FS (пробелы, т.е. е. на табах/пробелах ); nrf
- это просто временная переменная, которую я использовал, и она содержит количество полей, которые функция разделения ()выполняла.
затем мы использовали for -просмотр этих полей и проверку того, соответствует ли текущее поле tmp[i]
, которое читается, условиям, как вы ожидаете, если это так, мы печатаем, иначе мы проверяем следующее условие, если это было видно, затем печатаем в него одно предыдущее поле tmp[i-1]
, затем само текущее поле tmp[i]
, затем правое следующее поле к нему tmp[i+1]
, в противном случае мы печатаем пустую строку ""
.
Временные переменныеs1
иs2
используются для управления разделителем полей между первым и вторым действием условий печати, поэтому, если одно из них было найдено до того, как следующие поля должны печатать OFS раньше заранее.
Использование GNU awk для третьего аргумента для match()
, \<
границы слова и \s/\S
сокращения:
$ awk -v OFS='\t' 'match($0,/(\<DP4=\S+).*\s(\S+\tMODERATE\t\S+)/,a){print a[1], a[2]}' file
DP4=30,13,22,16 missense_variant MODERATE ABCB6