Удаление надмножеств строк из текстового файла

Один из способов добиться этого - использовать команду debsums .

$ debsums <package>

Пример

$ debsums xz-utils
/usr/bin/lzmainfo                                                             OK
/usr/bin/xz                                                                   OK
/usr/bin/xzdiff                                                               OK
/usr/bin/xzgrep                                                               OK
/usr/bin/xzless                                                               OK
/usr/bin/xzmore                                                               OK
/usr/share/doc/xz-utils/NEWS.Debian.gz                                        OK
/usr/share/doc/xz-utils/README.Debian                                         OK
/usr/share/doc/xz-utils/README.gz                                             OK
/usr/share/doc/xz-utils/copyright                                             OK
/usr/share/doc/xz-utils/extra/7z2lzma/7z2lzma.bash                            OK
/usr/share/doc/xz-utils/extra/scanlzma/scanlzma.c                             OK
/usr/share/doc/xz-utils/faq.txt.gz                                            OK
/usr/share/doc/xz-utils/history.txt.gz                                        OK
/usr/share/man/man1/lzmainfo.1.gz                                             OK
/usr/share/man/man1/xz.1.gz                                                   OK
/usr/share/man/man1/xzdiff.1.gz                                               OK
/usr/share/man/man1/xzgrep.1.gz                                               OK
/usr/share/man/man1/xzless.1.gz                                               OK
/usr/share/man/man1/xzmore.1.gz                                               OK
0
28.01.2019, 17:31
5 ответов
$ awk -F/ 'NF==3 { print }' filename

Мы устанавливаем разделитель полей равным /, а затем печатаем строки только с тремя полями. Предполагая, что формат вашего входного файла согласован, будут напечатаны только строки, такие как /a/b, поскольку три поля по порядку представляют собой пустую строку, aи b.

0
28.01.2020, 02:23

Предполагая, что ваш ввод отсортирован, как насчет проверки префикса и обновления его при изменении?

$ awk 'NR == 1 || ! match($0, "^" pfx) {print; pfx = $0}' file
/a/b
/a/c

ПРИМЕЧАНИЕ. :это соответствие регулярному выражению, поэтому оно может быть неприемлемым, если записи содержат специальные символы регулярного выражения. -FWIW ни gawk, ни mawkне рассматривают /как особое в этом контексте

2
28.01.2020, 02:23

Обязательно ли использовать awk? Греп может это сделать. Ты как-то так :egrep '^/a/b\$|/a/c\$'

В зависимости от вашей оболочки, $ может нуждаться или не нуждаться в экранировании обратной косой чертой.

0
28.01.2020, 02:23
gawk -F/ '
    {
        # have we seen something that is a prefix of this line?
        for (prefix in prefixes)
            if ($0 ~ "^" prefix)
                # yes we have
                next

        prefixes[$0] = 1

        # are there prefixes that get "cancelled out" by this new one?
        # e.g. /a/b/c is already a prefix but current line is /a/b
        for (prefix in prefixes)
            if (prefix ~ "^" $0 ".+")
                delete prefixes[prefix]
    }
    END {
        # GNU awk: traverse the array by index, sorted
        PROCINFO["sorted_in"] = "@ind_str_asc"
        for (p in prefixes)
            print p
    }
' list_of_dirs

выходы

/a/b
/a/c
/a/d/e
/a/e/f/g

Если у вас нет GNU awk, направьте вывод в| sort

1
28.01.2020, 02:23

Это можно сделать с помощью редактора sed, как показано:

$ sed -e '
   $!N
   \|^\(.*\)\n\1/|!{P;D;}
   s/\n.*//;H;s/.*//;x;D
' input_file

/a/b
/a/c
/a/d/e
/a/e/f/g

Рабочий:

  1. Обеспечьте наличие двух строк в пространстве шаблона в любое время.
  2. Если первая часть не находится в лидирующей позиции во второй части пространства шаблонов => они не относятся к одной и той же ветви. Мы печатаем первую часть, удаляем ее и возвращаемся к чтению следующей строки в пространство шаблонов и выполняем ту же проверку.
  3. В случае совпадения мы удаляем вторую часть, так как она больше (из-за допущения об отсортированном вводе ), поэтому мы сразу удаляем эту часть. И вернитесь и прочитайте следующую строку в пространство шаблона, и промойте/повторите.

Если входные данные не отсортированы, это можно сделать следующим образом:

$ perl -lne '
    my $l = $_;
    grep !index($l,$_), keys %h or $h{$_}++;
    }{print for sort keys %h;
' input
/a/b
/a/c
/a/d/e
/a/e/f/g

Работа:

  • index (str, substr )вернет индекс, в котором substr находится внутри str. Для совпадения в начале возвращается 0, который затем инвертируется по логическому типу, чтобы он читался как успех. grep будет перебирать все текущие ключи хеша %h, чьи ключи являются нужными нам подстроками.
0
28.01.2020, 02:23

Теги

Похожие вопросы