
У меня есть огромный список, как
67603;4716-5469-1335-0870;5450-7938-7992-5530;14523593;03 Oct 2016 - 17:01:15
63123;5592-6762-4853-6320;4532-4142-5613-9690;1441407;03 Oct 2016 - 17:01:15
62562;4532-5581-3790-0140;5292-4905-4356-2840;28898987;03 Oct 2016 - 17:01:15
68080;5188-1564-9611-7580;4556-9998-5999-3300;2262361;03 Oct 2016 - 17:01:15
Я хочу Поиск еще Повторяющиеся числа после 2 ; и перед 3-м ;
для первой строки номер 5450-7938-7992-5530
и другая строка 4532-4142-5613-9690
и т.д.
решение1
Рассмотрим следующий скрипт awk duplicates.awk
:
#!/usr/bin/awk -f
BEGIN {
RS = "(\r\n|\n\r|\r|\n)"
FS = "[\t\v\f ]*;[\t\v\f ]*"
split("", count)
}
{
count[$3]++
}
END {
for (item in count) {
if (count[item] > 1)
printf "%s\n", item
}
}
Не забудьте сделать его исполняемым, используя, например, chmod a+rx duplicates.awk
. Вы можете либо передать входные данные команде, либо указать один или несколько входных файлов в качестве параметров командной строки (несколько файлов обрабатываются так, как если бы они были объединены в один файл).
Правило BEGIN устанавливает универсальные новые строки (то есть принимает все соглашения о новых строках от MS-DOS до старых Mac и Unix) и точки с запятой ;
в качестве разделителя полей. Для иллюстрации я заставил разделитель полей также поглощать любые окружающие его пробелы, так что он x;foo bar ; y
разбирается на три поля: x
, foo bar
и y
.
Правило записи (средняя часть фрагмента) применяется к каждой записи (строке) во входных данных. Поскольку awk поддерживает ассоциативные массивы, мы просто используем третье поле, строку, как ключ к count
массиву и увеличиваем эту запись на единицу. (Увеличение несуществующей записи массива в awk дает 1, поэтому первое увеличение дает 1, и код работает так, как и ожидалось.)
Правило END сканирует count
массив, выводя записи, которые встречались как минимум дважды. Обратите внимание, что этот вывод находится в случайном порядке. (Существуют способы сортировки вывода по количеству вхождений или даже сохранения исходного порядка (первого вхождения) в файле, но OP не упомянул никаких требований к порядку, поэтому я не стал беспокоиться; неопределенный порядок — самый простой для реализации.)
Если вы хотите, например, вывести количество вхождений, за которыми следует строка (значение из третьего столбца), то вместо этого используйте следующее правило END:
END {
for (item in count)
printf "%15d %s\n", count[item], item
}
Вывод форматируется таким образом, что первые пятнадцать символов в выводе зарезервированы для числа, а значение начинается с 17-го символа.
решение2
Создание нескольких повторяющихся значений в файле stack.txt и последующая печать вывода -
67603;4716-5469-1335-0870;5450-7938-7992-5530;14523593;03 Oct 2016 - 17:01:15
63123;5592-6762-4853-6320;4532-4142-5613-9690;1441407;03 Oct 2016 - 17:01:15
62562;4532-5581-3790-0140;5292-4905-4356-2840;28898987;03 Oct 2016 - 17:01:15
68080;5188-1564-9611-7580;4556-9998-5999-3300;2262361;03 Oct 2016 - 17:01:15
67603;4716-5469-1335-0870;5450-7938-7992-5530;14523593;03 Oct 2016 - 17:01:15
63123;5592-6762-4853-6320;4532-4142-5613-9690;1441407;03 Oct 2016 - 17:01:15
62562;4532-5581-3790-0140;5292-4905-4356-2840;28898987;03 Oct 2016 - 17:01:15
68080;5188-1564-9611-7580;4556-9998-5999-3300;2262361;03 Oct 2016 - 17:01:15
67603;4716-5469-1335-0870;5450-7938-7992-5530;14523593;03 Oct 2016 - 17:01:15
63123;5592-6762-4853-6320;4532-4142-5613-9690;1441407;03 Oct 2016 - 17:01:15
Используйте следующую команду -
awk 'BEGIN{FS=";"}{a[$3]++} END {for(k in a) print a[k],k}' stack.txt
Выход -
3 4532-4142-5613-9690
2 5292-4905-4356-2840
3 5450-7938-7992-5530
2 4556-9998-5999-3300