Удаление ненужных строк из CSV-файла, имеющего более 10 шаблонов для сопоставления
У меня есть CSV
файл, который имеет 2 columns
и я должен match
значения в отдельной строке в обоих столбцах, если это соответствует критериям, мы должны сохранить столбец в противном случае delete
весь ряд. Ниже приведен пример моего CSV-файла:
lidocaine (oint, patch) generic 1 tube of cream
lidocaine (oint, patch) generic 1 kit
lidocaine (oint, patch) generic 1 bottle of topical solution
lidocaine (oint, patch) generic 1 tube of ointment
lidocaine (oint, patch) generic 1 tube of ointment
lidocaine (oint, patch) generic 1 jar of ointment
lidocaine (oint, patch) generic 1 bottle of lotion
lidocaine hcl (gel 2%, soln 4%) generic 1 patch
здесь, кроме строк 4-го, 5-го и 6-го, все остальные строки будут удалены. Причина этого заключается в следующем:
первый ряд имеет мазь и пятно слева, но крем справа, поэтому он будет удален.
Аналогичным образом будут удалены 2-й и 3-й ряды.
4-й, 5-й и 6-й ряды не будут удалены, потому что они имеют мазь слева и аналогичное слово мазь справа.
Так как же это реализовать programatically
так как у меня есть более 10 аналогичных условий, чтобы соответствовать, прежде чем строка будет удалена.
Пожалуйста, если кто-нибудь может мне помочь. Спасибо:)
1 ответ
Ой! опоздал на несколько лет, извините. Для полноты я добавлю ответ, связанный с bash.
Если вы не против запачкать руки регулярными выражениями, grep может стать вашим другом:
$ cat test.csv | grep -Es 'oint.*oint'
lidocaine (oint, patch) generic 1 tube of ointment
lidocaine (oint, patch) generic 1 tube of ointment
lidocaine (oint, patch) generic 1 jar of ointment
Здесь были отобраны только ряды с чем-то "мазью" посередине и снова "мазью".
Вы можете использовать оператор регулярного выражения 'или'
|
и добавьте другое условие, например, чтобы после слова 'gel' следовало x%, что является числом x от 1 до 20:
$ cat test.csv | grep -Es 'oint.*oint|gel (20|1[0-9]|[1-9])%'
lidocaine (oint, patch) generic 1 tube of ointment
lidocaine (oint, patch) generic 1 tube of ointment
lidocaine (oint, patch) generic 1 jar of ointment
lidocaine hcl (gel 2%, soln 4%) generic 1 patch
Я могу придумать этот скрипт Python, который принимает имя файла в качестве аргумента командной строки и выводит весь контент, но без всех строк, которые не имеют строки oint
(без учета регистра) во всех столбцах.
#! /usr/bin/env python3
import sys
COLUMN_SEPARATOR = " " # character or string used as column separator. Tab = "\t"
SEARCH_STRING = "oint".lower() # case-insensitive string that needs to be present in all columns
with open (sys.argv[1]) as f:
rows=[list(map(str.strip, line.split(COLUMN_SEPARATOR))) for line in f.readlines()]
for r in rows:
if all([SEARCH_STRING in r[i].lower() for i in range(len(r))]):
print(COLUMN_SEPARATOR.join(r))
Скопируйте скрипт выше и сохраните его как любой файл, например csvfilter.py
,
Сделайте его исполняемым с помощью chmod +x csvfilter.py
,
Затем запустите его с файлом для обработки в качестве одного аргумента.
Пример вывода с примером выше (столбцы разделены 3 пробелами) как source.csv
:
$ ./csvfilter.py source.csv
lidocaine (oint, patch) generic 1 tube of ointment
lidocaine (oint, patch) generic 1 tube of ointment
lidocaine (oint, patch) generic 1 jar of ointment
Сценарий не изменяет исходный файл, а просто печатает новую версию в стандартный вывод. Кроме того, любые пробельные символы между столбцами, кроме строки, установленной как COLUMN_SEPARATOR
будут отброшены
Чтобы заменить исходный файл измененной версией, перенаправьте вывод обратно в исходный файл:
$ ./csvfilter.py source.csv > source.csv
Вы также можете сохранить измененную версию в виде файла:
$ ./csvfilter.py source.csv > modified.csv