Ось веселий. Ви можете скористатися sedбезпосередньо, щоб зняти всі копії першого рядка і залишити все інше на своєму місці (включаючи сам перший рядок).
sed '1{h;n;};G;/^\(.*\)\n\1$/d;s/\n.*$//' input
1{h;n;}поміщає перший рядок у простір утримування, друкує його та читає у наступному рядку, пропускаючи решту sedкоманд для першого рядка. (Він також пропускає цей перший 1тест для другого рядка , але це не має значення, оскільки цей тест не застосовувався б до другого рядка.)
G додає новий рядок з подальшим вмістом простору утримування до простору шаблону.
/^\(.*\)\n\1$/dвидаляє вміст простору шаблону (таким чином, переходить до наступного рядка), якщо частина після нового рядка (тобто те, що було додано з місця утримування) точно відповідає частині перед новим рядком. Тут видаляються рядки, що дублюють заголовок.
s/\n.*$// видаляє частину тексту, яку додав G команда, так що друкується - це лише текст тексту з файлу.
Однак, оскільки регулярний вираз є дорогим, трохи швидшим підходом буде використання тієї самої умови (заперечення) та Pринг до нового рядка, якщо частина після нового рядка (тобто те, що додано з місця утримування) не точно відповідає частині перед новим рядком, а потім беззастережно видалити простір шаблону:
sed '1{h;n;};G;/^\(.*\)\n\1$/!P;d' input
Вихід, коли вводиться ваш внесок:
ID Data1 Data2
1 100 100
2 100 200
3 200 100
4 100 100
5 200 200
{ IFS= read -r head; printf '%s\n' "$head"; grep -vF "$head" ; } <file