Удалить список элементов из другого файла в bash

511
dronus

Каков наиболее эффективный метод (без повторного выполнения команды) для удаления элементов, перечисленных в одном файле, из другого файла (неупорядоченного)?

Можно легко получить список несоответствующих элементов во втором файле,

cat first_file.txt second_file.txt | sort | uniq -u 

но это также будет содержать все непревзойденные элементы из первого файла тоже ... что теперь?

0

1 ответ на вопрос

1
glenn jackman

Эта awkпрограмма проходит один проход через каждый файл:

awk ' NR == FNR  !($0 in f1) ' file1 file2 

comm полезно для этой работы. Это требует, чтобы его входные файлы были отсортированы:

# output lines unique to file2 comm -13 <(sort file1) <(sort file2) 
Я понятия не имею, как `! ($ 0 в f1)` работает внутри, я имею в виду __in__ внутри _awk_. Если он просто сканирует весь массив, мы должны иметь там O (n!). : - | _sort_ это, кажется, [высоко оптимизировано] (http://vkundeti.blogspot.ru/2008/03/tech-algorithmic-details-of-unix-sort.html) ... Есть ли у вас какие-либо ссылки о? Hastur 8 лет назад 0
оператор `in` проверяет, является ли левый операнд индексом (ассоциативного или индексированного) массива. Это должна быть операция O (1). Для gawk, документировано здесь: http://www.gnu.org/software/gawk/manual/html_node/Reference-to-Elements.html#Reference-to-Elements glenn jackman 8 лет назад 0
Спасибо за ссылку. __`in`__ должен сканировать полный массив `f1` не только одного элемента, отсюда O (n ^ 2) [Кстати, ошибки в предыдущем комментарии O (n ^ 2), а не O (n!)]. Я выполнил тест с 10 ^ 4 до 10 ^ 6 случайных строк по 32 байта, и решение awk масштабировалось линейно: он должен быть внутри порядка. (Решение `comm` более разнообразно: 2x при 10 ^ 4, ~ 1x при 10 ^ 5 и 2x 10 ^ 6, но я полагаю, это зависит от доступной памяти). Hastur 8 лет назад 0
Круто, я не знал про `комм` dronus 8 лет назад 0