awk как удалить дубликаты в полях, только если предыдущие поля совпадают - PullRequest
3 голосов
/ 24 января 2011

Я пытаюсь удалить дубликаты из полей (и заменить их пробелами), только если предыдущие поля совпадают.Например:

Пример ввода:

France  Paris      Museum of Fine Arts          blabala
France  Paris      Museum of Fine Arts          blajlk
France  Paris      Yet another museum           lqmsjdf
France  Paris      Museum of National History            mlqskjf
France  Bordeaux   Museum of Fine Arts          qsfsqf
France  Bordeaux   City Hall                lmqjflqsk
France  Bordeaux   City Hall                    lqkjfqlskjflqskfj
Spain   Madrid     Museum of Fine Arts          lqksjfh
Spain   Madrid     Museum of Fine Arts          qlmfjlqsjf
Spain   Barcelona  City Hall                nvqjvvnqk
Spain   Barcelona  Museum of Fine Arts          lmkqjflqksfj

Желаемый вывод:

France    Paris        Museum of FineArts                    blabala
                                                             blajlk
                       Yet another museum                    lqmsjdf
                       Museum of National History            mlqskjf
          Bordeaux     Museum of Fine Arts                   qsfsqf
                       City Hall                             lmqjflqsk
                                                             lqkjfqlskjflqskfj
Spain     Madrid       Museum of Fine Arts                   lqksjfh
                                                             qlmfjlqsjf
          Barcelona   City Hall                              nvqjvvnqk
                      Museum of Fine Arts                    lmkqjflqksfj

Большое спасибо за любую помощь.

Ответы [ 2 ]

1 голос
/ 24 января 2011

Попробуйте:

awk -F '\t' 'BEGIN {OFS=FS} {if ($1 == prev1) $1 = ""; else prev1 = $1; if ($2 == prev2) $2 = ""; else prev2 = $2; if ($3 == prev3) $3 = ""; else prev3 = $3; print}' inputfile

Вот более короткая версия, которая работает для любого количества полей (последнее поле всегда печатается):

awk -F '\t' 'BEGIN {OFS=FS} {for (i=1; i<=NF-1;i++) if ($i == prev[i]) $i = ""; else prev[i] = $i; print}' inputfile

Вывод не будет выровнен для использования на экране, но будет правильное количество вкладок.

Вывод будет выглядеть так:

field1 TAB field2 TAB field3 TAB field4
TAB TAB TAB field4
TAB TAB field3 TAB field4
TAB field2 TAB field3 TAB field4
etc.

Если вам нужно выровнять столбцы, это также возможно.

Edit:

Эта версия позволяет указывать поля для дедупликации:

#!/usr/bin/awk -f
BEGIN {
    FS="\t"; OFS=FS
    deduplist=ARGV[1]
    ARGV[1]=""
    split(deduplist,tmp," ")
    for (i in tmp) dedup[tmp[i]]=1
}
{
    for (i=1; i<=NF;i++)
        if (i in dedup) {
            if ($i == prev[i])
                $i = ""
            else
                prev[i] = $i
        }
    # prevent printing lines that are completely blank because 
    # it's an exact duplicate of the preceding line and all fields 
    # are being deduplicated
    if ($0 !~ /^[[:blank:]]*$/) 
        print
}

Запустите его так: ./script.awk "2 3" inputfile для дедупликации полей 2 и 3.

0 голосов
/ 24 января 2011

Попробуйте этот Perl однострочный:

perl  -F"\t" -nae '@O=@F;if(!$x){$x=1}else{for($i=0;$i<=$#S;$i++){$F[$i]=""if($S[$i] eq "" || $S[$i] eq $F[$i])}};print join "\t",@F;@S=@O;'

Посмотреть

Я предположил, что поля разделены табуляцией.

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