Удалите все строки в файле A, которые содержат строки в файле B

От корня Вашего выполненного дерева

find . -name \*cpp | while read FILE
do
    sed -i '1i #include "rootpath/headerfile.h"' "$FILE"
done
15
17.07.2014, 14:51
3 ответа

С помощью grep можно сделать:

$ grep -vwF -f toremove.txt users.txt 
username, userid, sidebar_side, sidebar_colour
"John Lennon", 90123412, "left", "blue"
"George Harrison", 72349482, "left", "green"

С помощью awk:

$ awk -F'[ ,]' 'FNR==NR{a[$1];next} !($4 in a)' toremove.txt users.txt 
username, userid, sidebar_side, sidebar_colour
"John Lennon", 90123412, "left", "blue"
"George Harrison", 72349482, "left", "green"
15
27.01.2020, 19:50

Вот ответ Gnouc awk , измененный так, чтобы не отображать пробелы:

awk -F, 'FNR==NR{a[$1];next} !(gensub("^ *","",1,$2) in a)' toremove.txt users.csv

Поскольку в качестве разделителей используются только запятые (а не пробелы), $ 1 - это «Джон Леннон» , $ 2 - 90123412 (с начальным пробелом) и т. Д. Поэтому мы используем gensub , чтобы удалить любое количество начальных пробелов из $ 2 прежде чем мы проверим, был ли он (идентификатор пользователя) в файле toremove.txt .

4
27.01.2020, 19:50

OK ruby способ: если у вас есть список строк в файле, и вы хотите удалить все строки из другого файла, которые даже содержат любую строку в первом файле (в этом случае удаление "file2" из "file1") ruby файл:

b=File.read("file2").split # subtract this one out
remove_regex = Regexp.new(b.join('|'))
File.open("file1", "r").each_line do |line|
  if line !~ remove_regex
    puts line
  end
end

к сожалению, при большом файле "для удаления" это, кажется, ухудшается по сложности до O(N^2) (я предполагаю, что regexp должен сделать много работы), но все же может быть полезным для кого-то там (если вы хотите больше, чем удаление полных строк). В некоторых случаях это может быть быстрее.

Другой вариант, если вам нужна скорость, - использовать тот же механизм проверки хэша, но тщательно "разбирать" строку на предмет строк, которые могут совпасть, а затем сравнивать их с вашим хэшем.

На языке ruby это может выглядеть так:

b=File.read("file2").split # subtract this one out
hash={}
for line in b
  hash[line] = 1
end

ARGF.each_line do |line|
  ok = true
  for number in line.scan(/\d{9}/)
    if hash.key? number
      ok=false
    end
  end
  if (ok)
    puts line
  end
end

Смотрите также ответ Скотта, он похож на ответы awk, предложенные на сайте hither thither, и позволяет избежать сложности O(N^2) (фух).

0
27.01.2020, 19:50

Теги

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