Как напечатать следующую или предыдущую строку, используя awk? - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть файл с 8 столбцами

1743 abc 04 10 29 31 34 35
1742 def 11 19 21 23 27 52
1741 ghi 15 18 20 32 48 49

, и у меня также есть строка awk, которая печатает всю строку, содержащую некоторые конкретные числа.Код -

awk -v col=1 '{ delete c; for (i=col; i<=NF; ++i) ++c[$i];
if (c['"$1"']>0 && c['"$2"']>0 && c['"$3"']>0 && c['"$4"']>0) print }' 
< input_file

(переменные $ 1, $ 2, $ 3 и $ 4 - потому что я использую его на bash).

В предыдущем примере, когда я ставил числа 1121 27 и 52 я получу строку 1742.

Как мне напечатать следующую или предыдущую строку?Как и в предыдущем примере, если я использую числа 11, 21, 27 и 52, как я получу строку 1743 или строку 1741?

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

другой подход с двойным сканированием

$ awk -v search="11 21 27 52" -v offset=-1 '
           NR==FNR {n=split(search,s); 
                    for(i=1;i<=n;i++) if(FS $0 FS !~ FS s[i] FS) next; 
                    line=NR; next} 
           FNR==line+offset' file{,}

1743 abc 04 10 29 31 34 35

Вы можете установить смещение на любое значение (не только -1,0,1).

NB Itтолько найти одно совпадение, если есть несколько совпадений, будет сообщено только последнее.Это можно сделать, сохранив совпадающие номера строк в массиве вместо скалярного значения (здесь line переменная).

0 голосов
/ 07 февраля 2019
$ cat a.sh
echo "BEFORE"

awk -v p1="$1" -v p2="$2" -v p3="$3" -v p4="$4" -v col=1 -f before.awk file

echo "AFTER"

awk -v p1="$1" -v p2="$2" -v p3="$3" -v p4="$4" -v col=1 -f after.awk file

Цитирование @triplee: «Чтобы напечатать предыдущую строку, запомните предыдущую строку в переменной.»

$ cat before.awk
prev { delete c;
  for (i=col; i<=NF; ++i) ++c[$i]
  if (c[p1]>0 && c[p2]>0 && c[p3]>0 && c[p4]>0) print prev
}
{ prev = $0 }

Снова, @triplee: «Чтобы напечатать следующую строку, помните, что выхотите, и напечатайте и сбросьте эту переменную на следующей итерации. "

$ cat after.awk
f { print; f = 0 }
{
  delete c;
  for (i=col; i<=NF; ++i) ++c[$i]
  if (c[p1]>0 && c[p2]>0 && c[p3]>0 && c[p4]>0) f = 1
}

$ ./a.sh 11 21 27 52
BEFORE
1743 abc 04 10 29 31 34 35
AFTER
1741 ghi 15 18 20 32 48 49
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...