perl -F, -lane '
exists $h{$F[0]} or $h[$h{$F[0]}=@h]=$_;
$h=$_; /,false$/ or $_=$h for $h[$h{$F[0]}];
END{ print for @h; }
' duplicates.file
Cấu trúc dữ liệu:
- Hash
%h
có khóa là các trường đầu tiên (AAA, BBB, CCC, v.v.) và các giá trị tương ứng là các số cho biết thứ tự mà các khóa gặp phải. Do đó, ví dụ: khóa AAA => 0, khóa BBB => 1, khóa CCC => 2.
- Mảng
@h
có các phần tử là các dòng chứa theo thứ tự in. Vì vậy, nếu cả hai đúng và sai được tìm thấy trong dữ liệu, thì giá trị sai sẽ đi vào mảng. OTW, nếu có một loại dữ liệu, thì nó sẽ xuất hiện.
Một cách khác là sử dụng GNU sed:
sed -Ee '
G
/^([^,]*),(false|true)\n(.*\n)?\1,\2(\n|$)/ba
/^([^,]*)(,true)\n(.*\n)?\1,false(\n|$)/ba
/^([^,]*)(,false)\n((.*\n)?)\1,true(\n|$)/{
s//\3\1\2\5/;h;ba
}
s/([^\n]*)\n(.*)$/\2\n\1/;s/^\n*//
h;:a;$!d;g
' duplicates.file
FWIW, mã tương đương POSIX cho mã GNU-sed ở trên được liệt kê bên dưới:
sed -e '
G
/^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2$/ba
/^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2\n/ba
/^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2$/ba
/^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2\n/ba
/^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false$/ba
/^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false\n/ba
/^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true$/{
s//\3\1\2/
h
ba
}
/^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true\n/{
s//\3\1\2\n/
h
ba
}
y/\n_/_\n/
s/\([^_]*\)_\(.*\)$/\2_\1/;s/^_*//
y/\n_/_\n/
h;:a;$!d;g
' duplicates.file
Giải trình
- Trong phương pháp này, chúng tôi lưu trữ kết quả cuối cùng sẽ được in trong không gian giữ.
- Đối với mỗi dòng được đọc, chúng tôi sẽ thêm không gian giữ vào không gian mẫu để kiểm tra dòng hiện tại để xem trạng thái hiện tại của không gian giữ.
- Bây giờ 5 điều có thể có thể xảy ra trong so sánh này:
- a) Dòng hiện tại khớp với một nơi nào đó trong dòng giữ & false: false.
- [HÀNH ĐỘNG] Vì cùng một trạng thái sai được tìm thấy, sau đó không làm gì cả.
- b) Dòng hiện tại khớp với một nơi nào đó trong dòng giữ & true: true.
- [HÀNH ĐỘNG] Vì cùng một trạng thái thực sự được tìm thấy, sau đó không làm gì cả.
- c) Dòng hiện tại khớp với một nơi nào đó trong dòng giữ & true: false.
- [HÀNH ĐỘNG] Vì một trạng thái sai đã tồn tại, không làm gì cả.
- d) Dòng hiện tại khớp với một nơi nào đó trong dòng giữ & false: true.
- [HÀNH ĐỘNG] Điều này liên quan đến một số công việc, trong đó chúng ta cần thay thế đường sai ở cùng một vị trí chính xác nơi đặt đúng.
- e) Dòng hiện tại KHÔNG khớp với bất kỳ nơi nào trong dòng giữ.
- [HÀNH ĐỘNG] Di chuyển dòng hiện tại đến cuối.
Các kết quả
AA,false
BB,false
CC,false
DD,true
true
nếu đó là phiên bản đầu tiên của cột đầu tiên?