Удалить все строки, кроме первого вхождения

Удалить все строки, кроме первого вхождения

Учитывая текстовый файл с разделителями-пробелами, найдите шаблон в первом столбце. Если он найден, сохраните первое вхождение и удалите остальные строки:

Ввод (шаблон = 1234):

1234    1111    2222
5678    3333    4444
1234    5678    9012
5678    1234    5678
1234    9786    5432

Ожидаемый результат:

1234    1111    2222
5678    3333    4444
5678    1234    5678

решение1

Поэтому вы хотите напечатать все строки, где первое поле не является указанным значением, и напечатать первую строку, где оно совпадает.

awk -vF="$1" '{ if ($1 != F) { print; } else {if (!seen) { print ; seen=1}}}'

Использует тот факт, что переменные awk ( seenв данном случае) изначально имеют значение 0.

решение2

Сохранить первую совпадающую строку и удалить все последующие совпадающие строки с помощью GNU sed:

sed -e '/^1234/{x;/./!{x;h;b;};d}' file

Объяснение:

/^1234/когда шаблонный буфер соответствует ^1234

x- поменять местами шаблон и буфер хранения (при первом совпадении буфер хранения будет пуст, поэтому буфер шаблона теперь, что самое важное, пуст)

/./!- Буфер шаблонов теперь пуст?

{x;h;b;}- затем поменять местами (x) шаблон и буфер хранения (это помещает текущую строку обратно в буфер шаблона), скопировать буфер шаблона в старый буфер (h) и перейти к концу выполнения для этой строки (b) - т.е. загрузить следующую строку и снова запустить код sed. Последнее (d) удаление не выполняется.

d- после первого совпадения буфер хранения будет содержать копию строки macthing, поэтому блок {x;h;b;} выше не будет выполнен - ​​вместо этого текущая строка удаляется, программа завершается, следующая строка загружается в буфер шаблона, и программа запускается снова.

Связанный контент