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
Структуры данных:
- Хеш
%h, ключи которого являются первыми полями (AAA, BBB, CCC и т. Д.), А соответствующие значения являются числами, указывающими порядок, в котором встречались ключи. Таким образом, например, ключ AAA => 0, ключ BBB => 1, ключ CCC => 2.
- Массив
@h, элементами которого являются строки, содержащиеся в порядке печати. Таким образом, если в данных найдены как истина, так и ложь, тогда ложное значение попадет в массив. OTW, если есть один тип данных, то это будет присутствовать.
Другой способ - использовать 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, эквивалентный код POSIX для приведенного выше кода GNU-sed приведен ниже:
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
объяснение
- В этом методе мы сохраняем результат, который будет окончательно распечатан, в области хранения.
- Для каждой прочитанной строки мы добавляем пространство удержания к пространству шаблона для проверки текущей строки относительно существующего состояния пространства удержания.
- Теперь 5 вещей могут произойти во время этого сравнения:
- a) Текущая строка совпадает где-то в линии удержания & false: false.
- [ДЕЙСТВИЕ] Так как это же ложное состояние найдено, то ничего не делать.
- б) Текущая строка совпадает где-то в линии удержания & true: true.
- [ДЕЙСТВИЕ] Так как это же истинное состояние найдено, то ничего не делать.
- c) Текущая строка совпадает где-то в линии удержания & true: false.
- [ДЕЙСТВИЕ] Поскольку ложное состояние уже существует, ничего не делать.
- г) Текущая строка совпадает где-то в линии удержания & false: true.
- [ДЕЙСТВИЕ] Это включает в себя некоторую работу, в которой мы должны заменить ложную линию в той же самой позиции, где находится истина.
- д) Текущая строка НЕ совпадает нигде в линии удержания.
- [ДЕЙСТВИЕ] Переместить текущую строку до конца.
Результаты
AA,false
BB,false
CC,false
DD,true
trueесли это первый экземпляр первого столбца?