2014-10-05 2 views
0

Это, наверное, простой вопрос для ниндзя командной строки, но я не могу понять это для жизни меня. На данный момент я использую PHP-скрипт для выполнения этого, но мне нужно сделать это с помощью awk/sed/cut или аналогичного.Как удалить строки с одним и тем же средним блоком?

У меня есть файл журнала, как это:

123 | foo | 12.13 
756 | bar | 14.25 
236 | baz | 11.23 
536 | foo | 10.13 
947 | bar | 34.25 
134 | baz | 11.26 

Мне нужно удалить все строки, имеет средний элемент же. Если там является дубликат, необходимо сохранить более новую версию. Выходной файл после удаления должны выглядеть следующим образом:

536 | foo | 10.13 
947 | bar | 34.25 
134 | baz | 11.26 

Я новичок в этом и не имею ни малейшего представления о том, как это сделать, так что немного подтолкнуть в нужном направлении было бы большим подспорье.

ответ

1
$ tac file | awk -F' +[|] +' '!seen[$2]++' | tac 
536 | foo | 10.13 
947 | bar | 34.25 
134 | baz | 11.26 

o г, если вы предпочитаете AWK только решение:

$ awk -F' +[|] +' 'NR==FNR{fnr[$2]=FNR; next} FNR==fnr[$2]' file file 
536 | foo | 10.13 
947 | bar | 34.25 
134 | baz | 11.26 
1

Вы можете использовать эту awk команду, используя пользовательский разделитель полей:

awk -F' *\\| *' '!data[$2]{a[++k]=$2} {data[$2]=$0} 
      END{for (i=1; i<=k; i++) print data[a[i]]}' file 
536 | foo | 10.13 
947 | bar | 34.25 
134 | baz | 11.26 
1

Если вы не заботитесь о порядке вывода

perl -F'\s*\|\s*' -lanE '$s{$F[1]}=$_}{say $s{$_} for keys %s' <ca.txt 

отпечатки

134 | baz | 11.26 
947 | bar | 34.25 
536 | foo | 10.13 
0
sed -e ":a 
$ !{N;ba 
    } 
:b 
s/[0-9]* | \([^ ]*\) | [0-9.]*\n\(.*\)\1/\2\1/g 
t b" YourFile 

СЕПГ Posix версию (так --posix для GNU СЭД особенно из-за использования | внутри s///)

Смежные вопросы