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

У меня есть многие .csv файлы (некоторые преобразованные из xlsx), и я пытаюсь извлечь электронные письма и веб-сайты из тех файлов.

Данные в файлах похожи:

Daniel,Rose,DR@example.com,http://www.example.com,1234567890
Daniel1,Rose,DR1@example.com,http://www.example.com,1234567890
Daniel2,Rose,DR2@example.com,http://example.com,1234567890
Daniel3,Rose,DR3@example.com,www.example.com,1234567890
Daniel4,Rose,DR4@example.com,1234567890,example.com

Я просто хочу извлечь электронные письма и веб-сайты с клиентом в этом csv.
Вывод должен быть похожим на это:

DR@example.com
http://www.example.com 
DR1@example.com
http://www.example.com
DR3@example.co
www.example.com
DR4@example.com
2
задан 2 February 2017 в 19:25

2 ответа

Базирующийся простой текст, определенно больше подробной опции Python:

#!/usr/bin/env python3
import sys

f = sys.argv[1]; out = sys.argv[2]

with open(out, "wt") as wr:
    with open(f) as read:
        for l in read:
            for s in l.strip().split(","):
                if any(["@" in s, "www" in s, "http" in s]):
                    wr.write(s+"\n")

Или, только для забавы, немного более сжатой:

#!/usr/bin/env python3
import sys

with open(sys.argv[2], "wt") as wr:
    with open(sys.argv[1]) as read:
        [[wr.write(s+"\n") for s in l.strip().split(",") if any(["@" in s, "www" in s, "http" in s])] for l in read]

Использовать

  • Скопируйте сценарий в пустой файл, сохраните его как get_stuff.py
  • Выполните его с исходным файлом и предназначенным выходным файлом как аргументы:

    python3 /path/to/get_stuff.py <input_file> <output_file>
    

Результат:

DR@example.com
http://www.example.com
DR1@example.com
http://www.example.com
DR2@example.com
DR3@example.com
www.example.com
DR4@example.com

Сравнение вовремя

Интересный видеть то, что на меньших файлах (как в примере), sed опция быстрее, но на больших файлах опция Python быстрее:

на файле 150 000 строк:

sed

real    0m0.073s
user    0m0.068s
sys     0m0.000s

Python

real    0m0.046s
user    0m0.044s
sys     0m0.000s

На файле с 10 строками:

sed

real    0m0.003s
user    0m0.000s
sys     0m0.000s

Python

real    0m0.037s
user    0m0.032s
sys     0m0.000s

(Я должен упомянуть, что у меня есть древнее поле, все случаи должны быть короче на серьезной машине),

Идея могла состоять в том, что особенно, если необходимо извлечь данные из многих меньших файлов в цикле, используйте sed, на больших файлах в цикле, используйте Python.

На единственном файле, маленьком или большом, различие между 0.073и 0.046 полностью не важно.


Дополнительно

Ниже версии для извлечения тех же данных из целого (простого) каталога файлов.

#!/usr/bin/env python3
import sys
import os

dr = sys.argv[1]

def extract(f, out):
    with open(out, "wt") as wr:
        with open(f) as read:
            [[wr.write(s+"\n") for s in l.strip().split(",") if any(
                ["@" in s, "www" in s, "http" in s]
                )] for l in read]

for file in os.listdir(dr):
    f = os.path.join(dr, file); out = os.path.join(dr, "extracted_"+file)
    extract(f, out)

Из каждого из файлов сценарий создаст новый файл с извлеченными данными. Из файла:

somefile.csv

это создаст второй файл, названный:

extracted_somefile.csv
4
ответ дан 2 December 2019 в 01:36

Я чувствую, что Ваш желаемый вывод пропускает 2 строки?

$ sed -r 's|.*,([^,]+@[^0-9]+),.*|\1|' file | tr ',' '\n'
DR@example.com
http://www.example.com
DR1@example.com
http://www.example.com
DR2@example.com
http://example.com
DR3@example.com
www.example.com
DR4@example.com

В противном случае затем разъяснитесь.

Объяснение

  • -r используйте ДО
  • s|old|new| замена old с new
  • .*, любые символы, заканчивающиеся запятой
  • ([^,]+@[^0-9]+),.* сохраните некоторые символы незапятой перед @, затем некоторые символы, которые не являются числами перед запятой - соответствуют чему-либо после этого, таким образом, мы можем отбросить ее
  • \1 обратная ссылка на сохраненный шаблон
  • tr ',' '\n' измените остающиеся запятые в новые строки (я обратился к передаче по каналу к tr потому что поля не последовательны, но вероятно этого можно избежать умно),
3
ответ дан 2 December 2019 в 01:36

Другие вопросы по тегам:

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