Как удалить строки, которые появляются в файле B, из другого файла A?

У меня есть большой файл A (состоящий из писем), по 9X_fgrep одной строке на каждое письмо. У меня также 9X_pgrep есть еще один файл B, содержащий другой набор 9X_shell-commands писем.

Какую команду я бы использовал для 9X_sed удаления всех адресов, которые появляются 9X_sed в файле B, из файла A.

Итак, если файл A 9X_egrep содержал:

A
B
C

и файл B содержал:

B    
D
E

Затем в файле 9X_grep A нужно оставить:

A
C

Теперь я знаю, что это 9X_shell-trap вопрос, который, возможно, задавали чаще, но 9X_pgrep я обнаружил только one command online, который дал мне ошибку 9X_shell с плохим разделителем.

Любая помощь будет 9X_shell-commands принята с благодарностью! Кто-нибудь наверняка 9X_grep придумает хитрый однострочник, но я не эксперт 9X_shell-trap по оболочке.

204
2

  • возможный дубликат [Удаление строк из одного файла, которые находятся в д ...
9
Общее количество ответов: 9

Ответ #1

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

Если файлы отсортированы (они есть в вашем 9X_shellscript примере):

comm -23 file1 file2

-23 подавляет строки, которые находятся 9X_diff в обоих файлах или только в файле 2. Если 9X_shell-script файлы не отсортированы, сначала пропустите 9X_shell-command их через sort ...

См. man page here

240
3

  • В качестве альтернативы используйте `comm -23 file1 file2 | губка file1`. Очистка не требует ...

Ответ #2

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

grep -Fvxf

  • работает с несортированными файлами
  • поддерживает порядок
  • is POSIX

Пример:

cat < A
b
1
a
0
01
b
1
EOF

cat < B
0
1
EOF

grep -Fvxf B A

Вывод:

b
a
01
b

Пояснение:

  • -F: используйте буквальные строки вместо стандартного BRE
  • -x: учитывать только совпадения, соответствующие всей строке
  • -v: распечатать несоответствие
  • -f file: взять шаблоны из заданного файла

Этот метод работает 9X_shellscript медленнее с предварительно отсортированными 9X_shell-scripting файлами, чем другие методы, поскольку он 9X_diff более общий. Если скорость тоже имеет значение, см. Fast way of finding lines in one file that are not in another?

Вот 9X_shell-scripting быстрая автоматизация bash для оперативной 9X_shell работы:

remove-lines() (
  remove_lines="$1"
  all_lines="$2"
  tmp_file="$(mktemp)"
  grep -Fvxf "$remove_lines" "$all_lines" > "$tmp_file"
  mv "$tmp_file" "$all_lines"
)

GitHub upstream.

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

remove-lines lines-to-remove remove-from-this-file

См. также: https://unix.stackexchange.com/questions/28158/is-there-a-tool-to-get-the-lines-in-one-file-that-are-not-in-another

118
0

Ответ #3

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

awk спешит на помощь!

Это решение не требует 9X_pgrep сортировки входных данных. Сначала вы должны 9X_shellscript предоставить файл B.

awk 'NR==FNR{a[$0];next} !($0 in a)' fileB fileA

возвращает

A
C

Как это работает?

NR==FNR{a[$0];next} идиома предназначена 9X_shellscript для хранения первого файла в ассоциативном 9X_grep массиве в качестве ключей для более позднего 9X_egrep теста "содержит".

NR==FNR проверяет, сканируем ли 9X_sed мы первый файл, где глобальный счетчик строк 9X_shell (NR) равен текущему счетчику строк файла 9X_diff (FNR).

a[$0] добавляет текущую строку в ассоциативный 9X_diff массив в качестве ключа, обратите внимание, что 9X_pgrep это ведет себя как набор, где не будет никаких 9X_grep повторяющихся значений (ключей)

!($0 in a) Теперь мы 9X_shell-commands находимся в следующем файле (ах), in - это 9X_shellscript тест на содержание, здесь он проверяет, находится 9X_shell ли текущая строка в наборе, который мы заполнили 9X_linux на первом шаге из первого файла, ! отменяет 9X_diff условие. Здесь не хватает действия, которое 9X_pgrep по умолчанию имеет значение {print} и обычно не 9X_diff записывается явно.

Обратите внимание, что 9X_sed теперь это можно использовать для удаления 9X_shellscript слов из черного списка.

$ awk '...' badwords allwords > goodwords

с небольшим изменением 9X_fgrep он может очищать несколько списков и создавать 9X_grep очищенные версии.

$ awk 'NR==FNR{a[$0];next} !($0 in a){print > FILENAME".clean"}' bad file1 file2 file3 ...

71
0

Ответ #4

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

Другой способ сделать то же самое (также 9X_shell-scripting требуется отсортированный ввод):

join -v 1 fileA fileB

В Bash, если 9X_pgrep файлы не отсортированы заранее:

join -v 1 <(sort fileA) <(sort fileB)

19
0

Ответ #5

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

Вы можете сделать это, если ваши файлы не 9X_shell-scripting отсортированы

diff file-a file-b --new-line-format="" --old-line-format="%L" --unchanged-line-format="" > file-a

--new-line-format для строк, которые находятся 9X_diff в файле b, но не в a --old-.. предназначен для строк, которые 9X_shell-commands находятся в файле a, но не в b --unchanged-.. предназначен 9X_shell-script для строк, находящихся в обоих. %L делает 9X_shellscript так, чтобы строка печаталась точно.

man diff

подробнее

9
2

  • Это было ответом на вышеприведенное решение, в котором предлагалось использовать команду `comm`. `comm` требует, чтобы файлы были отсортированы, поэтому, если они отсорт ...

Ответ #6

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

Это уточнение красивого ответа @karakfa 9X_shell может быть заметно быстрее для очень больших 9X_diff файлов. Как и в случае с этим ответом, ни 9X_diff один файл не нужно сортировать, но скорость 9X_shellscript обеспечивается ассоциативными массивами 9X_shell-commands awk. В памяти хранится только файл поиска.

Эта 9X_shell-trap формулировка также допускает возможность 9X_linux того, что при сравнении будет использоваться 9X_shell-scripting только одно конкретное поле ($ N) во входном 9X_shell-script файле.

# Print lines in the input unless the value in column $N
# appears in a lookup file, $LOOKUP;
# if $N is 0, then the entire line is used for comparison.

awk -v N=$N -v lookup="$LOOKUP" '
  BEGIN { while ( getline < lookup ) { dictionary[$0]=$0 } }
  !($N in dictionary) {print}'

(Еще одно преимущество этого подхода 9X_shell-scripting состоит в том, что критерий сравнения легко 9X_fgrep изменить, например, обрезать начальные и 9X_diff конечные пробелы.)

8
0

Ответ #7

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

Вы можете использовать Python:

python -c '
lines_to_remove = set()
with open("file B", "r") as f:
    for line in f.readlines():
        lines_to_remove.add(line.strip())

with open("file A", "r") as f:
    for line in [line.strip() for line in f.readlines()]:
        if line not in lines_to_remove:
            print(line)
'

9X_sed

2
0

Ответ #8

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

Вы можете использовать - diff fileA fileB | grep "^>" | cut -c3- > fileA

Это будет работать 9X_diff и для файлов, которые не отсортированы.

2
0

Ответ #9

Ответ на вопрос: Как удалить строки, которые появляются в файле B, из другого файла A?

Чтобы добавить к ответу Python пользователю 9X_pgrep выше, вот более быстрое решение:

    python -c '
lines_to_remove = None
with open("partial file") as f:
    lines_to_remove = {line.rstrip() for line in f.readlines()}

remaining_lines = None
with open("full file") as f:
    remaining_lines = {line.rstrip() for line in f.readlines()} - lines_to_remove

with open("output file", "w") as f:
    for line in remaining_lines:
        f.write(line + "\n")
    '

Повышение 9X_shell-scripting мощности вычитания множеств.

2
0