2013-09-13 2 views
1

У меня есть список, в котором есть данные в паре с IP-адресами, и я хочу только один раз увидеть IP-адрес, и я не хочу менять порядок.Как удалить отдельные повторяющиеся строки в файле в linux

 
192.168.0.100 fred is happy 
192.168.0.100 fred likes pie 
192.168.0.100 pie is good 
192.168.0.110 tom like cake 
192.168.0.110 cake is good 
192.168.0.110 pie is better 
192.168.0.112 bill like lettuce 
192.168.0.112 lettuce is good for you 
192.168.0.112 cake and pie are better tasting than lettuce 

Что я хочу сделать, это просто удалить дублирующий IP-адрес, но оставить все точно таким же.

Я хочу, чтобы это выглядело как этот

 
192.168.0.100 fred is happy 
       fred likes pie 
       pie is good 
192.168.0.110 tom like cake 
       cake is good 
       pie is better 
192.168.0.112 bill like lettuce 
       lettuce is good for you 
       cake and pie are better tasting than lettuce 

Я не хочу коснуться любого из повторяющихся слов, и я не могу изменить порядок

Спасибо вам, если вы можете помочь

ответ

1

Я думаю, разделитель между IP и текст tab, то это один вкладыш должен работать для вас:

awk -F'\t' -v OFS='\t' 'a[$1]{gsub(/./," ",$1);print;next}{a[$1]=1}7' file 

тест с файлом:

kent$ awk -F'\t' -v OFS='\t' 'a[$1]{gsub(/./," ",$1);print;next}{a[$1]=1}7' f 
192.168.0.100 fred is happy 
       fred likes pie 
       pie is good 
192.168.0.110 tom like cake 
       cake is good 
       pie is better 
192.168.0.112 bill like lettuce 
       lettuce is good for you 
       cake and pie are better tasting than lettuce 
+0

Я был неправ я не получил его на работу сепаратора пространства. –

1

Использование AWK:

awk 'BEGIN{FS=OFS=" "}{t=$1;if(t in a){gsub(/./," ",$1);a[t]=a[t]RS$0}else{a[t]=$0}}END{for(i in a)print a[i]}' file 

Выход:

192.168.0.100 fred is happy 
       fred likes pie 
       pie is good 
192.168.0.110 tom like cake 
       cake is good 
       pie is better 
192.168.0.112 bill like lettuce 
       lettuce is good for you 
       cake and pie are better tasting than lettuce 
+1

Спасибо konsolebox, мне пришлось сделать небольшую настройку, но я добрался туда, где мне нужно с вашим примером. –

+1

Это может полностью переупорядочить вывод любезности оператора 'in' - вывод будет в порядке обхода хэш-карты массивов, которая может не быть порядком ввода. –

+0

@EdMorton Я действительно предполагаю, что Gawk устанавливает его в порядок всегда, если что-то не удалено, но это неправильно? Представляя реализацию awk, новый ключ всегда будет добавляться в конце списка в любом случае. – konsolebox

0

Это может работать для вас (GNU СЭД):

sed -r '1{:a;p;h;s/\s.*//;s/./ /g;H;d};G;s/^(\S+)(\s.*)\n\1.*\n(.*)/\3\2/;t;s/\n.*//;ba' file 

Печать первой записи и те записи, где ключ изменяет и сохраняет ключ и его дополнение в пространствах в пространстве удержания. Для последующих записей сравнивайте сохраненный ключ с текущим ключом и для тех, которые соответствуют замене текущего ключа дополнением пробелов. Для тех ключей, которые не соответствуют, удаляют сохраненный ключ и дополняют и повторяют с самого начала.

2

Это не будет работать независимо от того, какой интервал и/или RE метасимволов находятся в файле: «»

$ awk ' 
{ key = $1 } 
key == prev { sub(/[^[:space:]]+/,sprintf("%*s",length(key),"")) } 
{ prev = key; print } 
' file 
192.168.0.100 fred is happy 
       fred likes pie 
       pie is good 
192.168.0.110 tom like cake 
       cake is good 
       pie is better 
192.168.0.112 bill like lettuce 
       lettuce is good for you 
       cake and pie are better tasting than lettuce 

Берегись решений, использующих $ 1 в контексте RE, как те, с в качестве IP-адреса являются метасимволами RE, которые означают «любой символ», поэтому они могут работать для некоторых выборочных данных, но вы можете получить ложные совпадения с учетом другого ввода.

1

еще один:

awk 'A[$1]++{s=$1; gsub(/./,FS,s); sub($1,s)}1' file 
+0

1 Nice! Немного подумал, чтобы убедить себя, что у этого финального суб ($ 1, s) не будет проблем с «.s» в «$ 1», но я не думаю, что они будут с начального «A [$ 1] ++ 'гарантирует, что строка начинается с того же самого' $ 1', который вы используете в sub(), поэтому '.' будет выстраиваться в линию. –

+0

Спасибо @EdMorton, действительно, точки ERE всегда будут соответствовать буквальным здесь :-) .. – Scrutinizer

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