İşte eğlenceli bir tane. sed
İlk satırın tüm kopyalarını çıkartmak ve diğer her şeyi (ilk satırın kendisi dahil) yerinde bırakmak için doğrudan kullanabilirsiniz .
sed '1{h;n;};G;/^\(.*\)\n\1$/d;s/\n.*$//' input
1{h;n;}
ilk satırı bekleme alanına yerleştirir, yazdırır ve sonraki satırda okur sed
; ilk satır için komutların geri kalanını atlar . (Ayrıca , ilk 1
testin ikinci satır için atlanmasını sağlar , ancak bu testin ikinci satıra uygulanmayacağı için bu önemli değildir.)
G
desen alanına bir satırsonu ve ardından tutma alanının içeriği ekler.
/^\(.*\)\n\1$/d
eğer yeni satırdan sonraki kısım (yani, tutma alanından eklenenler) yeni satırdan önceki kısımla tam olarak eşleşiyorsa, desen alanının içeriğini siler (böylece bir sonraki satıra atlar). Burası, başlığı kopyalayan satırların silineceği yerdir.
s/\n.*$//
metnin G
komut tarafından eklenmiş kısmını siler , böylece yazdırılacak dosya yalnızca dosyadaki metin satırı olur.
Bununla birlikte, normal ifade pahalı olduğu için, aynı koşulu kullanmak (olumsuzlanmış) kullanmak ve P
eğer yeni satırdan sonraki bölüm (yani, tutma alanından eklenen) bölümle tam olarak eşleşmiyorsa , yeni satıra kadar gitmek için biraz daha hızlı bir yaklaşım olacaktır. satır sonundan önce ve ardından desen alanını koşulsuz olarak silin:
sed '1{h;n;};G;/^\(.*\)\n\1$/!P;d' input
Girdiniz verildiğinde çıktı:
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