Как удалить все вхождения значений в одном списке из другого списка?

у меня есть список символов, таких как...

wer
sfe
efo

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

так в следующем списке, строки, начинающиеся с wer будет удалено дважды, и sfe после:

wer-alskjdfi
efr-4siosejf
rte-alskjdfs
wer-alskjsef
sfe-ooskjdfi

каждая вторая строка должна быть нетронутой, с символом и символами после " -":

efr-4siosejf
rte-alskjdfs

мне нужно сделать это с помощью sed / awk / grep / bash или другой команды линейные инструменты. Я знаю, как написать команду sed для поиска и удаления одного значения за раз, но как это сделать для значений 100k+?

5
задан barrrista
источник

4 ответов

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

хорошо, сделайте копию file2, который имеет только поле, которое вы хотите отфильтровать по.  Причем, если ток file2 имеет "неуникальный символ"тут затем "конечными символами "(например,efr-42,rte-17, etc.), сделайте еще одну копию file2, где они разделены пробелами.  Вот примеры команд на основе предоставленных вами данных:

sed 's/\(...\).*//'        file2.sorted > file2.symbol_only
sed 's/\(...\)\(.*\)/ /' file2.sorted > file2.separated

или

sed 's/\([^-]*\)-.*//'        file2.sorted > file2.symbol_only
sed 's/\([^-]*\)\(-.*\)/ /' file2.sorted > file2.separated

... на основе новых данных, которые вы добавили в свой вопрос.  Тогда используйте comm до

comm -13 file1.sorted file2.symbol_only > file2.no_match

... и соедините символы с конечными символами:

join file2.no_match file2.separated

при необходимости использовать другой sed удалить добавленные пробелы.


мне пришло в голову, что вы могли бы построить на этом трюке, чтобы получить выходной файл обратно в file2 первоначальный заказ.

  1. Создать копию оригинала file2 с номерами строк.
  2. перемешать номера строк справа от символов.
  3. (выше, начиная с sort команды)
  4. Сортировать вывод по оригинальному номеру.
  5. удалить номера строк.

Дайте мне знать, если вам нужна помощь с этим.

1
отвечен Scott 2012-11-20 21:24:01
источник

предполагая, что ваши списки находятся в файлах

awk -F- 'NR==FNR {exclude[]++; next} !( in exclude)' list_of_symbols filename

греп тоже вариант

grep -v -f <(sed 's/^/^/' list_of_symbols) filename

бит sed добавляет якорь регулярного выражения в начало каждой строки.

2
отвечен glenn jackman 2012-11-20 23:35:43
источник

вам нужно сохранить порядок вашего второго файла?  Можете ли вы указать максимальное количество повторений строки?  Если ответы на оба вопроса "нет", я бы предложил comm:

sort file1 file1 > file1.sorted     sort file2 > file2.sorted
-------------------------------     -------------------------
efo                                 efr
efo                                 rte
sfe                                 sfe
sfe                                 wer
wer                                 wer
wer

comm -13 file1.sorted file2.sorted
efr
rte

включить достаточно копии file1 in file1.sorted, чтобы покрыть максимальное количество вхождений любой строки в file2.

1
отвечен Scott 2012-11-20 19:41:14
источник

ничего не зная о SED и т. д., основной дизайн в моем личном псевдокоде:

сортировка списка удаляемых строк (List A)

сортировка списка строк, содержащих удаляемые элементы (List B)

для каждого элемента списка A

Repeat until Item (List B) > Item (List A)
    if the Item (List B) equals Item (List A) 
        remove item (List B)
    next Item (List B)
Next Item (List A)

Примечание: "удаление" элемента может быть проблематичным-лучше заменить эту строку одним добавлением элемента к новому

0
отвечен Fred 2012-11-20 19:27:39
источник

Другие вопросы awk bash grep linux sed