![Поиск отсутствующего порядкового номера в файле данных](https://rvso.com/image/97231/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA%20%D0%BE%D1%82%D1%81%D1%83%D1%82%D1%81%D1%82%D0%B2%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE%20%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE%20%D0%BD%D0%BE%D0%BC%D0%B5%D1%80%D0%B0%20%D0%B2%20%D1%84%D0%B0%D0%B9%D0%BB%D0%B5%20%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85.png)
Как выполнить поиск в большом файле с «последовательными номерами» (которые сбрасываются после 16) в определенном столбце, чтобы найти отсутствующую строку?
У меня есть файл данных:
col1 col2 col3 col4 col5 1
col1 col2 col3 col4 col5 2
.
.
.
col1 col2 col3 col4 col5 15
col1 col2 col3 col4 col5 16
col1 col2 col3 col4 col5+1 1
где последний столбец отсчитывает от 1 до 16, а затем сбрасывается обратно до 1. В этот момент 1 добавляется к столбцу 5.
Чистый вывод просто повторялся бы до конца файла. Как мне найти недостающие данные, например
col1 col2 col3 col4 col5 1
col1 col2 col3 col4 col5 3
где строка была пропущена/потеряна, как видно из последнего столбца, в котором пропущено значение 2?
Мне бы хотелось получить в качестве желаемого вывода номер строки/расположение строки до или после отсутствующих данных.
Этот ответ на Stack Overflowнатолкнуло меня на мысль использовать awk
. Итак, вот что я придумал:
awk '$6!=p+1{print NR}{p=$6}'
Попытаться напечатать номер текущей строки, когда столбец 6 текущей строки не равен столбцу 6 последней строки +1. Это не удается из-за циклической природы перехода к 16 и возврата к 1.
решение1
$ cat -n file
1 col1 col2 col3 col4 col5 14
2 col1 col2 col3 col4 col5 15
3 col1 col2 col3 col4 col5 16
4 col1 col2 col3 col4 col5 1
5 col1 col2 col3 col4 col5 2
6 col1 col2 col3 col4 col5 15
7 col1 col2 col3 col4 col5 16
8 col1 col2 col3 col4 col5 4
9 col1 col2 col3 col4 col5 5
$ awk '{if (p % 16 + 1 != $6) printf("line %d is bad: %s\n", NR, $0); p=$6}' file
line 1 is bad: col1 col2 col3 col4 col5 14
line 6 is bad: col1 col2 col3 col4 col5 15
line 8 is bad: col1 col2 col3 col4 col5 4
Чтобы понять значение оператора деления по модулю «%» (остаток от деления), вы можете поэкспериментировать с этим фрагментом awk:
$ yes | head -n 40 | awk '{x=NR-1; print x, "->", x % 16}'
0 -> 0
1 -> 1
2 -> 2
[...]
14 -> 14
15 -> 15
16 -> 0
17 -> 1
18 -> 2
[...]