Можно использовать perl
нулевая ширина оглядывается regex синтаксис.
perl -pe "s/(?<=[aeiou])([^aeiou_]*)[aeiou]([^aeiou_]*)/\1\2/ig"
Этот следующий отрывок рассматривает входную строку как единственную строку (не несколько подстрок).
perl -pe "s/(?<=[aeiou])([^aeiou]*)[aeiou]/\1/ig"
С awk
, Вы могли сделать:
awk -F, -vOFS=, '{l=$0; $3=""}; ! ($0 in seen) {print l; seen[$0]}'
Самый простой путь:
sort -u -t, -k1,2 -k4
-u
: вывод только первая строка равняется-t,
: используйте запятую в качестве разделителя полей-k1,2 -k4
: вид только на полях 1,2 и 4 и остальныхДругая опция перестраивает данные с sed
(отметьте опцию GNU -r
) с обеих сторон - это требует, чтобы записи были главным образом фиксированной длиной, иначе она собирается перестать работать (и только едва заметно):
sed -r 's/^([^,]+,[^,]+)(,[^,]+)(.*)$/\1\3\2/' \
| sort \
| uniq -w 12 \
| sed -r 's/^([^,]+,[^,]+)(.*)(,[^,]+)$/\1\3\2/'
Вы могли бы хотеть добавить другого sort
в конце для упорядочивания его числами, при желании (используют -k
опция выбрать согласно тому, как что вид должен быть выполнен - т.е. что-то sed -k3 -t,
)
В Perl Вы могли, например, использовать части, на которых Вы хотите решить уникальность как ключи в хеше (значения сплошные линии) и вставить в хеш, только если ключ еще не определяется. Это, конечно, будет намного более гибко, чем использование sed
(или awk
), но также и больше записи (я далек от Гуру Perl, таким образом, вероятно, что это может быть сделано намного более изящным способом - см. другие ответы для подобных Perl решений для Perl):
#!/usr/bin/perl
use strict;
my %lines;
while (<>) {
(my $k1, my $v, my $k2) = /^([^,]+,[^,]+,)([^,]+)(,.*)$/;
my $k = $k1 . $k2;
if (!exists($lines{$k})) {
$lines{$k} = $_;
}
}
for my $k (sort(keys(%lines))) {
print $lines{$k};
}
$lines{$k} = $_ unless $lines{$k};
– cas
17.09.2013, 14:15
uniq
полевые опции и не могли, не думал для использования sort
-u
. По тому, как я думаю это sort -u
расширение GNU, не POSIX, но это будет хорошо работать в системах Linux.
– terdon♦
17.09.2013, 20:41
perl
один) Однако как общий новобранец Perl, это потребовало, чтобы я немного прочитайте руководство понял то, что Вы делали здесь. %lines
(легко распознаваемый его знаком процента), ассоциативный массив (иначе, "хешируют переменную" в малопонятном жаргоне Perl), который может принять "реальные" строки как ключевые идентификаторы, не просто индексы. Это - элемент, ответственный за все это удивительное "волшебство", сделанное здесь.
– syntaxerror
09.08.2015, 14:42
Способ сделать это с awk | sort | uniq | awk
:
awk -F, '{a=$1;$1=$3;$3=a;print}' file | sort -k 2 | uniq -f 1 | awk -v OFS=',' '{a=$1;$1=$3;$3=a;print}'
Более простой Perl путь был бы:
perl -F"," -ane '$a=join(",",@F[0,1,3 .. $#F]); print unless $k{$a}; $k{$a}++' file
-a
поля разделений в @F
массив и -F","
устанавливает разделитель полей на ,
. -n
средства запускают скрипт, данный -e
на каждой строке входного файла.
Идея состоит в том, чтобы взять часть массива (элементы 0,1 и 3 до конца массива), присоединиться к ним в строку ($a
) и используйте ту строку в качестве хеша (ассоциативный массив) ссылка. Вы затем печатаете каждую строку, только если ключ хеша не был замечен прежде.
ab,c,1,d
и a,bc,2,d
то же. Вам нужно join(","
. Также можно оптимизировать путем перемещения $k{$a}++
в unless() { }
блок. И затем, который был бы эквивалентен моему awk
решение ;-).
– Stéphane Chazelas
17.09.2013, 20:10
ab,c,1,d
и a,bc,2,d
как идентичное - сравнение сделано на восстановленной строке (с запятыми в правильных местах).
– peterph
17.09.2013, 20:25
join(","
.
– terdon♦
17.09.2013, 20:26
$k{$a}++
если $a
уже находится в %k
. Вы могли сделать его короче с: perl -F, -ane'print if!$k{join",",@F[0,1,3..-1]}++'
– Stéphane Chazelas
17.09.2013, 22:25