跳转到主要内容

CSV处理和Web相关数据类型的相互转换

项目描述

Convey

Build Status Downloads

Swiss knife for mutual conversion of the web related data types, like base64 or outputs of the programs whois, dig, curl. A convenient way to quickly gather all meaningful information or to process large files that might freeze your spreadsheet processor.

任何输入都被接受

  • 如果检测到单个值输入,则获取所有有意义的信息
  • 多行 base64/quoted_printable 字符串将被解码
  • log/XLS/XLSX/ODS文件 转换为CSV
  • CSV文件(任何分隔符,标题或pandoc表格格式)执行一个或多个操作
    1. 选择、删除或排序列(如果只需要某些列)
    2. 添加列(从另一个字段计算一个字段 - 见下文)
    3. 筛选(保留/丢弃具有特定值的行,无重复)
    4. 按列拆分(产生单独的文件而不是单个文件;然后可以通过通用的SMTP或通过OTRS发送这些文件)
    5. 更改CSV方言(更改分隔符或引号字符,删除标题)
    6. 汇总(按列分组计数,求和...)
    7. 合并(连接其他文件)

需要Python3.7+(旧版本支持3.6)。

目录

用法

用法1 - 单个查询

检查如果提供 IP 会发生什么,它返回包含与 WHOIS 相关信息和抓取的 HTTP 内容的表格。

$ convey 1.1.1.1 # single query input
Input value detected: ip

1.1.1.1 ...au

field             value
----------------  -----------------
prefix            1.1.1.0-1.1.1.255
asn               as13335
abusemail         abuse@apnic.net
country           au
netname           apnic-labs
csirt-contact     -
incident-contact  au
status            200
text              DNSThe free app that makes your (much longer text...)

用法2 - CSV处理器程序

解析 CSV 文件。

$ convey my-file-with-ips.csv # will trigger file parsing
Source file: /tmp/my-file.csv
Log lines: 200

Sample:
...

Delimiter character found: ','
Quoting character: '"'
Header is present: not used

Could you confirm this? [y]/n
...
...

用法3 - 网络服务

再次,让我们向 网络服务 提供一个 IP,它返回包含与 WHOIS 相关信息和抓取的 HTTP 内容的 JSON。

$ convey --server  # start a UWSGI session

在浏览器中访问: http://localhost:26683/?q=example.com

{"ip": "93.184.216.34", "prefix": "93.184.216.0-93.184.216.255", "asn": "", "abusemail": "abuse@verizondigitalmedia.com", "country": "unknown", "netname": "edgecast-netblk-03", "csirt-contact": "-", "incident-contact": "unknown", "status": 200, "text": "DNSThe free app that makes your (much longer text...)"}

安装和首次运行

先决条件

  • 如果系统中没有安装,第一次运行时会要求您安装 dialog 库。
  • 如果您的系统缺少某些东西,您可以使用以下命令自行找到帮助:sudo apt install python3-pip python3-dev python3-tk git xdg-utils dialog whois dnsutils nmap curl build-essential libssl-dev libpcre3 libpcre3-dev && pip3 install setuptools wheel uwsgi && pip3 install --upgrade ipython
    • build-essential 是构建 uwsgienvelope 所必需的
    • libpcre3 libpcre3-dev 是必要的,以抑制 uWSGI 警告 !!! 无内部路由支持,请使用 pcre 支持重新构建 !!!
    • libssl-dev 是必需的,在构建 uwsgi 之前需要存在,如果您需要使用 --https

作为包启动

# (optional) setup virtual environment
python3 -m venv venv
. venv/bin/activate
(venv) $ ... # continue below

# install from PyPi
pip3 install convey  # without root use may want to use --user

# (optional) alternatively, you may want to install current master from GitHub
pip3 install git+https://github.com/CZ-NIC/convey.git

# launch
convey [filename or input text] # or try `python3 -m convey` if you're not having `.local/bin` in your executable path

参数 [filename or input text] 可能是 CSV 源文件的路径或任何应解析的文本。注意,如果文本只包含一个值,程序将打印出所有可计算的信息并退出;例如,输入 base64 字符串将对其进行解码。

或者从目录启动

# download from GitHub
git clone git@github.com:CZ-NIC/convey.git
cd convey
pip3 install -r requirements.txt  --user

# launch
./convey.py

Bash完成

  1. 运行:apt-get install bash-completion jq
  2. 复制:extra/convey-autocompletion.bash/etc/bash_completion.d/
  3. 重启终端

自定义

  • Convey 尝试使用默认 GUI 编辑器或如果 GUI 不是选项,则在终端编辑器中打开文件。
  • 如果工作目录中存在 config.ini,则使用该文件而不是用户配置文件夹中的文件。
  • 升级时自动更新配置。

计算字段

可计算字段

某些字段类型可以直接计算

  • abusemail – 从 whois 获取滥用电子邮件联系信息
  • asn – 从 whois 获取
  • base64 – 编码/解码
  • cc_contact – 与 abusemail 对应的电子邮件地址,从您的个人 contacts_cc CSV 中获取,格式为 domain,cc;cc(邮件由分号分隔)。此文件的路径必须在 config.ini » contacts_cc 中指定。
  • country – 从 whois 获取的国家代码
  • csirt_contact – 与国家代码对应的电子邮件地址,从您的个人 contacts_abroad CSV 中获取,格式为 country,abusemail。此文件的路径必须在 config.ini » contacts_abroad 中指定
  • external – 您在自定义 .py 文件中指定方法,该方法接收字段并为您生成值,请参阅下面
  • hostname – 从 url 获取域名
  • incident_contact – 如果IP来自本地国家(在config.ini » local_country中指定),则该字段获取abusemail,否则我们获取country@@mail,其中mailabusemail或国外国家的电子邮件。通过此字段拆分后,convey可以随后将拆分的文件发送到本地滥用和外国csirt联系人。
  • ip – 从URL翻译而来
  • netname – 来自whois
  • prefix – 来自whois

Whois模块

获取WHOIS记录时

  • 我们内部调用whois程序,检测请求了哪些服务器。
  • 有时你会遇到一个有趣的格式化的whois响应。我们试图减轻此类情况,并在已知情况下向另一个注册机构重新提问。
  • 由于同一前缀中的IP地址共享相同的信息,我们将其缓存以获得最大速度,同时减少whois查询。
  • 有时你会遇到一个没有信息但断言其前缀包含大量地址空间的IP。该部分的所有IP地址最终都被标记为未知。在处理结束时,你将被要求逐个重做未知项以完成缺失信息,清除缓存中的误导性超集。
  • 你可能很容易达到LACNIC查询率配额。在这种情况下,如果可能,我们将重新排队此类行,在配额过后进行查询。处理结束时,你将被询问是否希望仔细且缓慢地重新处理等待配额提升的行。

可检测字段

某些字段类型可能可以自动检测

  • ip – 标准IPv4 / IPv6地址
  • cidr – CIDR表示法,例如:127.0.0.1/32
  • port_ip – 形式为1.2.3.4.port的IPv4
  • any_ip – 形式为any text 1.2.3.4 any text的IPv4
  • hostname – 或FQDN;第二或第三域名
  • url – 以http/https开头的URL
  • asn – AS号码
  • base64 – 使用base64编码的文本
  • wrong_url – 被替换某些字符后停用的URL,例如:"hxxp://example[.]com"

所有方法概述

当前字段计算能力可以通过--show-uml标志获取。通过例如convey --show-uml | dot -Tsvg -o /tmp/convey-methods.svg生成你的。

  • 虚线节点:字段类型可自动检测
  • 虚线边:字段类型相同
  • 边标签:运行时请求的生成选项
  • 矩形:字段类别边框

Methods overview

外部字段教程

简单自定义方法

如果您希望计算一个外部字段,请准备一个内容可以像这样简单的文件

def any_method(value):
    # do something
    return "modified :)"
启动外部方法
  • 在CSV处理过程中,点击'添加列'并选择'从您的.py文件中添加新外部...'
  • 或在终端中将--field external附加到您的convey命令。将出现一个用于Python文件路径和所需方法的对话框。
$ convey [string_or_filepath] --field external
  • 您可以直接指定路径和可调用项。因为--field具有以下语法

FIELD[[CUSTOM]],[COLUMN],[SOURCE_TYPE],[CUSTOM],[CUSTOM]

您可以省略COLUMNSOURCE_TYPE,并按此方式编写

FIELD,COLUMN,SOURCE_TYPE,CUSTOM,CUSTOM external,/tmp/myfile.py,any_method

$ convey [string_or_filepath] --field external,/tmp/myfile.py,any_method
Input value seems to be plaintext.
field     value
--------  -----------------------
external  modified :)
注册外部方法
  • 您还可以在config.ini中通过提供入口点Python文件的路径(用逗号分隔)来硬编码自定义字段:external_fields = /tmp/myfile.py, /tmp/anotherfile.py。定义文件中的所有公共方法将成为自定义字段!
[EXTERNAL]
external_fields = /tmp/myfile.py
  • 如果不需要,您可以通过向EXTERNAL部分添加新项逐个注册。用冒号分隔方法名称。
[EXTERNAL]
any_method = /tmp/myfile.py:any_method

可能的结果列表

如果您需要单个调用生成多行,则返回列表,接受列表的行将被复制。

def any_method(value):
    # do something
    return ["foo", "bar"]

当convey接收到多个列表时,它会为每个组合生成一行。例如:如果一个方法返回2个项目,另一个返回3个项目,你将收到6个类似的行。

PickMethod 装饰器

如果你的生成器有多个使用方式,将它们作为带有PickMethod装饰器的类的成员方法,并让用户在运行时决定。 PickMethod有可选的default:str参数,用于指定默认方法。

from convey import PickMethod

@PickMethod("all")
class any_method(PickMethod):
    def all(x):
        ''' All of them.  '''
        return x

    def filtered(cls, x):
        ''' Filter some of them '''
        if x in country_code_set:
            return x
$ convey file.csv --field any_method  # user will be asked whether to use `all` or `filtered`
$ convey file.csv --field any_method[filtered]  # `filtered` sub-method will be used
$ convey file.csv --field any_method --yes  # the default `all` sub-method will be used

PickInput 装饰器

如果你需要在每次处理之前直接让用户输入,导入PickInput并让您的函数接受两个参数。后者将由用户设置,并可能具有默认值。

from convey import PickInput
import dateutil

@PickInput
def time_format(val, format="%H:%M"):
    ''' This text will be displayed to the user.
        If running in headless mode, the default format will be "%H:%M" (hours:minutes).   '''
    return dateutil.parser.parse(val).strftime(format)
$ convey file.csv --field time_format  # user will be asked for a format parameter
$ convey file.csv --field time_format[%M]  # `format` will have the value `M%`
$ convey file.csv --field time_time --yes  # the default `format` `%H:%M` will be used

网络服务

当作为网络服务启动时,有几个参数可用

  • q – 搜索查询

  • type – 与--type CLI标志相同

  • field – 与--field CLI标志相同。

    • 请注意,默认情况下,网络服务禁用了不安全的字段类型codeexternal。您可以在webservice_allow_unsafe_fields配置选项中重新允许它们。
    • 支持CLI标志的全语法

    FIELD[[CUSTOM]],[COLUMN],[SOURCE_TYPE],[CUSTOM],[CUSTOM]

    例如:reg_s,l,L执行将'l'替换为'L'的常规替换

  • clear=web – 清除网络爬取模块缓存

可以通过一个命令实现快速部署

$ convey --server
  • 请注意,必须通过pip安装convey
  • 请注意,LACNIC可能冻结300秒,因此建议超时。
  • 请注意,您可以通过运行pip3 show convey找到您的convey安装路径
  • 如果您收到或生成了密钥和证书,您可以在uwsgi.ini中打开HTTPS,该配置可通过convey --config uwsgi访问
  • 内部,标志--server使用UWSGI会话启动wsgi.py
    $ uwsgi --http :26683 --http-timeout 310 --wsgi-file /home/$USER/.local/lib/python3.../site-packages/convey/wsgi.py
    

访问:curl http://localhost:26683/?q=example.com

{"ip": "93.184.216.34", "prefix": "93.184.216.0-93.184.216.255", "asn": "", "abusemail": "abuse@verizondigitalmedia.com", "country": "unknown", "netname": "edgecast-netblk-03", "csirt-contact": "-", "incident-contact": "unknown", "status": 200, "text": "DNSThe free app that makes your (much longer text...)"}

访问:curl http://localhost:26683/?q=example.com&field=ip

{"ip": "93.184.216.34"}

访问:curl http://localhost:26683?q=hello&type=country&field=reg_s,l,L

{"reg_s": "heLLo"}

发送文件

当您通过电子邮件将CSV文件分割成块时,生成的文件可以发送到这些地址。查看下面解锁的“发送”菜单示例。您可以看到收件人列表,然后是已经发送的收件人的条件列表。接下来,打印出精确的电子邮件消息,包括标题。

在菜单中,您可以

  • 发送电子邮件
  • 限制一次发送的消息数量;如果您不确定是否想一次性发送整个消息桶。
  • 编辑模板。消息文件将在默认GUI或终端编辑器中打开。模板的第一行应该是Subject: ...,后面跟一个空行。请注意,您可以包含任何电子邮件标题,如Reply-To: ...Cc: ...等。电子邮件将反映所有这些。您可以使用纯文本或HTML编写消息。
  • 选择哪些收件人将在复选框列表中接收消息。
  • 测试发送消息到您自己的地址。您将提示哪些消息应该发送给您。发送前将显示可能通过动态模板修改的电子邮件内容。
  • 打印所有电子邮件到文件以对将要发送的内容有更细粒度的控制。
  • 切换文件附加开/关。与该电子邮件地址相关的源文件的一部分可能会附加。有些情况下,您可能不希望将文件作为正文文本发送。
  • 切换路径列中的附加开/关。在路径列中提到的与该电子邮件地址相关的文件可能会附加。
  *** E-mail template ***
Recipient list (1/3): alice@example.com
Already sent (2/3): bob@example.com, cilia@example.com
Attachment: split CSV file attached

Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
Subject: My subject
From: me@example.com
Date: Fri, 17 Jan 2020 01:36:28 +0100

Hello,

this is my testing message.

Keen regards

**************************************************
1) Send all e-mails via localhost (1) ←←←←←
l) Limit sending amount to...
e) Edit template...
r) Choose recipients...
t) Send test e-mail...
p) Print e-mails to a file...
a) Attach files (toggle): True
i) Attach paths from path column (toggle): False
x) Go back...
?

任意电子邮件头,"From" 头,GPG 签名

在模板中,您可以指定任何电子邮件标题,例如 Reply-ToCcFrom。如果找不到 From,我们则使用 SMTP/email_from_name 配置值。如果默认用户路径上找到 gnupg 主目录,我们将检查是否存在与 From 标题匹配的秘密密钥,如果找到,电子邮件将被 GPG 签名。如果将要签名,您会在电子邮件模板预览中看到类似 Content-Type: multipart/signed; protocol="application/pgp-signature"; 的标题。

动态模板

默认情况下,消息将通过 Jinja2 模板系统进行处理。

包括一些工具来处理附件内容

  • attachment() – 打印附件内容并防止其被附加。

    You will find our findings below.
    
    {{ attachment() }}
    
  • row() – 逐行生成附件内容字段。跳过标题。

  • amount(count=2) – 检查附件是否有至少 count 行。标题不计入。在决定结果中是单行还是多行时很有用。

  • joined(column: int, delimiter=", ") – 返回由分隔符连接的列

  • first_row – 访问第一行字段

    示例

    {% if amount() %}
        Here is the complete list of the elements.
        {{ joined(1,"\n") }}
    {% else %}
        Here is the element you had problems with: {{ first_row[1] }}
    {% endif %}
    

示例

在示例中,我们将使用这些参数来添加字段并缩短结果。

# -f, --field adding field syntax: FIELD[[CUSTOM]],[COLUMN],[SOURCE_TYPE],[CUSTOM],[CUSTOM]
# -H, --headless: just quietly print out single value, no dialog

URL 解析

输出格式

将任何 IP 或 URL 作为参数。

$ convey example.com
Input value detected: hostname

Whois 93.184.216.34... abuse@verizondigitalmedia.com
Scrapping http://example.com...
field             value
----------------  ------------------------------------------------------------------------------
cidr              93.184.216.0/24
ip                93.184.216.34
tld               com
url               http://example.com
abusemail         abuse@verizondigitalmedia.com
csirt_contact     -
incident_contact  abuse@verizondigitalmedia.com
netname           edgecast-netblk-03
prefix            93.184.216.0-93.184.216.255
a                 93.184.216.34
aaaa              2606:2800:220:1:248:1893:25c8:1946
mx                0 .
ns                ['a.iana-servers.net.', 'b.iana-servers.net.']
spf               v=spf1 -all
http_status       200
text              Example Domain
                  This domain is for use in illustrative examples in documents. You may use this
                   domain in literature without prior coordination or asking for permission.
                  More informatio
                  n...

如果您只需要域名/IP所在的国家的国家,请使用 --field, -f 参数

$ convey wikipedia.com -f country
Input value detected: hostname

Whois 208.80.154.232... us
field    value
-------  -------
country  us

使用 --headless, -H--quiet, -q 标志来缩短输出(并减少所有对话框)。

$ convey wikipedia.com -f country -H
us

标志 --json 修改输出。

$ convey wikipedia.com -f country -H --json
{"country": "us"}

从另一列计算 TLD

要从用于 IP 域名的主机中使用的 abusemail 计算顶级域(TLD),添加一个 abusemail 字段,然后另一个 tld 字段。具体来说,后者应从第二列(即 abusemail)获取数据 - 要么输入 '2',要么输入 'abusemail'。

$ convey example.com -f abusemail -f tld,2
$ convey example.com -f abusemail -f tld,abusemail
Input value detected: hostname

Whois 93.184.216.34... abuse@verizondigitalmedia.com
field      value
---------  -----------------------------
abusemail  abuse@verizondigitalmedia.com
tld        com

要防止 abusemail 输出,请使用 --field-excluded, -fe 而不是 --field, -f

$ convey example.com -fe abusemail -f tld,2 -H
Input value detected: hostname

Whois 93.184.216.34... abuse@verizondigitalmedia.com
field    value
-------  -------
tld      com

我们之前没有说过,每次都会询问用户他们是否想要获取任何 tldgTLD(例如:com)或 ccTLD(例如:cz)。您可以通过 CLI 中的等效命令之一来指定它。

$ convey test.csv --fresh --field tld[gTLD]
$ convey test.csv --fresh --field tld,,,gTLD

# flag --yes or --headless will choose the default option which is *all*
$ convey test.csv --fresh --field tld --yes

CSV 处理

如果您有一份您想要丰富其位于的 CIDR 的对象的列表,请加载它们所在的 test.csv 文件。

# file text.csv
domain list
wikipedia.com
example.com

只需添加 --field cidr 参数即可查看菜单。

$ convey test.csv -f cidr
Source file: /tmp/ram/test.csv
Identified columns:
Log lines: 3

Sample:
domain list
wikipedia.com
example.com

Delimiter character found: ','
Quoting character: '"'
Header is present: yes

Could you confirm this? [y]/n: (HIT ENTER)

Source file: /tmp/ram/test.csv, delimiter: ',', quoting: '"', header: used
Identified columns: domain list (hostname)
Computed columns: cidr (from domain list)
Log lines: 3

Sample:
domain list
wikipedia.com
example.com

Whois 208.80.154.232... us
Whois 93.184.216.34... abuse@verizondigitalmedia.com
Preview:
domain list      cidr from:
   (hostname)    domain list
---------------  ---------------
wikipedia.com    208.80.152.0/22
example.com      93.184.216.0/24

Main menu - how the file should be processed?
1) Pick or delete columns
2) Add a column
3) Filter
4) Split by a column
5) Change CSV dialect
6) Aggregate
7) Merge
p) process ←←←←←
~) send (split first)
~) show all details (process first)
r) redo...
c) config...
x) exit
?

文件拆分

我们将创建一个 ASN 字段,并将 file.csv 文件按此字段分割,而不将其添加到输出中。

# file.csv
wikipedia.com,443,2016-02-09T01:12:26-05:00,16019,US
seznam.cz,25,2016-02-27T22:20:21-05:00,16019,CZ
google.com,25,2016-02-28T02:27:21-05:00,16019,US
$ convey file.csv --field-excluded asn --split asn
(...)
** Processing completed: 3 result files in /tmp/ram/file.csv_convey1573236314
(...)
# file as14907
wikipedia.com,443,2016-02-09T01:12:26-05:00,16019,US
# file as43037
seznam.cz,25,2016-02-27T22:20:21-05:00,16019,CZ
# file as15169
google.com,25,2016-02-28T02:27:21-05:00,16019,US

CSIRT 用例

CSIRT 可以使用该工具来自动化事件处理任务。输入是我们从合作伙伴那里收到的任何 CSV;至少有一列包含 IP 地址或 URL。我们获取 whois 信息,并生成一系列按国家 AND/OR 与 IP 相关的 abusemail 分组的 CSV。然后,通过工具内的 OTRS 发送这些 CSV。大部分工作都由这个命令完成。

convey --field-excluded incident_contact,source_ip --split incident_contact --yes [FILENAME]

自定义代码字段

从自定义 Python 代码添加列

$ convey example.com -f code,"x=x[1:5]"
xamp

Base64 和正则表达式

在此处编写代码,然后返回

$ convey hello -f base64  -H  # --headless conversion to base64
aGVsbG8=
$ convey aGVsbG8= -H  # automatically identifies input as base64 and produces plaintext
hello

使用 reg 列进行正则表达式。

# start adding a new reg column wizzard that will take decoded "hello" as input
$ convey aGVsbG8= -f reg
$ convey aGVsbG8= -f reg_s,"ll","LL" -H   # substitute 'll' with 'LL'
heLLo

指定源

# start adding a new reg column wizzard that will take plaintext "aGVsbG8=" as input
$ convey aGVsbG8= -f reg,plaintext
# specifying plaintext as a source type will prevent implicit convertion from base64
$ convey aGVsbG8= -f reg_s,plaintext,"[A-Z]","!" -H  # substitute uppercase letters with '!'
a!!sb!8=

单位转换

我们已连接到 pint 单位转换器!

$ convey "3 kg"
Input value detected: unit

field      value
---------  --------------------------------------------------------------------------------------------
plaintext  ['1.806642538265029e+27 atomic_mass_unit', '105.82188584874123 ounce', '96.45223970588393 ap
           othecary_ounce', '0.0703602964419822 bag', '0.05905239165666364 long_hunderweight', '0.06613
           867865546327 US_hundredweight', '0.002952619582833182 UK_ton', '0.002952619582833182 long_to
           n', '1929.0447941176785 pennyweight', '46297.07505882429 grain', '1.7935913792661326e+27 pro
           ton_mass', '771.6179176470714 apothecary_dram', '3000.0 gram', ...]


$ convey "3 kg" -f unit # launches wizzard that let's you decide what unit to convert to
$ convey "3 kg" -f unit[g] -H
3000.0 gram

$ convey "kg" -f unit --csv-processing --headless
kg|6.022141794216764e+26 atomic_mass_unit
kg|0.001 metric_ton
kg|0.0009842065276110606 UK_ton
kg|771.6179176470714 scruple
kg|257.2059725490238 apothecary_dram
kg|1000.0 gram


# You may try to specify the units with no space and quotation.
# In the following example, convey expand all time-units it is able to compute
# – time units will be printed out and each is base64 encoded.
$ convey 3hours
Input value detected: timestamp, unit

field                value
-------------------  ------------------------------------------------------------------
(...)
base64               ['MC4wMDQxMDY4NjM4OTc0NTAwNzcgbW9udGg=', 'MTA4MDAuMCBzZWNvbmQ=', 'MC4wMTc4NTcxNDI4NTcxNDI4NSB3ZWVr']
plaintext            ['0.004106863897450077 month', '10800.0 second', '0.01785714285714285 week', (...)]
time                 03:00:00
(...)

# What if
$ convey 3hours -f urlencode
Input value detected: timestamp, unit

Input unit_expand variable unit: *you type here sec or seconds to see the wizzard*
Preview
| original   | result         |
|------------|----------------|
| 3hours     | 10800.0 second |

field      value
---------  ----------------
urlencode  10800.0%20second

# What if we wanted to urlencode text "3hours" without converting it to unit first?
# Just specify the SOURCE_TYPE to be plaintext:
$ convey "3hours" -f urlencode,plaintext
Input value detected: timestamp, unit

field      value
---------  -------
urlencode  3hours

国家名称

当指定国家代码时,您将获得国家名称。

$ convey --type country sc
Seychelles

许多国家可以识别。

bash
$ convey --type country_name Futuna
wf

您可以从各种电话号码格式中获取国家代码。

$ convey +2481234567
Seychelles

$ convey "1-541-754-3010"
['ca', 'us']

$ convey

聚合

语法是 [COLUMN, FUNCTION], ..., [group-by-COLUMN]。可能的功能包括

  • avg
  • sum
  • count
  • min
  • max
  • list
  • set

让我们有一个文件。

# file.csv
category,price,consumption
bulb,100,30
bulb,150,10
kettle,250,70
kettle,352,80
bulb,120,15

计算 price 列的总和。

$ convey file.csv --aggregate price,sum
  sum(price)
------------
         972

categoryprice 总和进行分组。

$ convey file.csv --aggregate price,sum,category
category     sum(price)
---------  ------------
total               972
bulb                370
kettle              602

categoryprice 总和和 consumption 平均值进行分组。

$ convey file.csv --aggregate price,sum,consumption,avg,category
category      sum(price)    avg(consumption)
----------  ------------  ------------------
total                972               41
bulb                 370               18.33
kettle               602               75

categoryprice 总和进行分组,并列出其值。

$ convey file.csv --aggregate price,sum,price,list,category
category      sum(price)  list(price)
----------  ------------  ---------------------
total                972  (all)
bulb                 370  ['100', '150', '120']
kettle               602  ['250', '352']

您甚至可以在聚合时进行拆分。每个文件将计算自己的结果。

$ convey file.csv --agg price,sum --split category

Split location: bulb
  sum(price)
------------
         370

Split location: kettle
  sum(price)
------------
         602

合并

您可以根据公共列合并两个文件。

想象一个名为 person.xls 的 XLS 文件,包含以下行

john@example.com,foo,male
mary@example.com,foo,female
hyacint@example.com,bar,male

以及一个文件 sheet.csv

foo,red,second.example.com
foo,green,first.example.com
bar,blue,wikipedia.org
bar,yellow,example.com
foo,orange,wikipedia.com

使用单个命令将它们合并。我们指定合并的文件将是 person.xls,而公共列(foo/bar)在远程文件中是第二个,在本地的 sheet.csv 文件中是第一个。

$ convey --output --headless --file sheet.csv --merge person.xls,2,1
foo,red,second.example.com,mary@example.com,female
foo,red,second.example.com,john@example.com,male
foo,green,first.example.com,mary@example.com,female
foo,green,first.example.com,john@example.com,male
bar,blue,wikipedia.org,hyacint@example.com,male
bar,yellow,example.com,hyacint@example.com,male
foo,orange,wikipedia.com,mary@example.com,female
foo,orange,wikipedia.com,john@example.com,male
  • 当枢轴键(本地列值)
    • 在远程文件中缺失时,该行的字段将保持空白。
    • 出现两次时,该行会被复制。
  • 性能提示:处理非常大的文件?虽然您要合并的本地文件可以任意大小,但合并的远程文件不应过大,它应该适合内存。

向不同收件人发送图片

假设您有一个充满 PNG 文件的目录,包含各自域管理员的详细信息。

example.com.png
example.com-2.png
wikipedia.org.png
csirt.cz.png

我们想向 example.com 的管理员发送两张图片,向 wikipedia.orgcsirt.cz 发送一张。首先,创建一个 CSV 文件,其中第一列是域名,第二列是对应的图片。为此,我们使用pz库。

pip3 install pz  # install `pz` if needed
ls *.png | pz 're.sub("-\d+$", "", Path(s).stem),s' > domains_images.csv

CSV 文件 domains_images.csv 现在看起来是这样的

example.com	example.com-2.png
example.com	example.com.png
wikipedia.com	wikipedia.com.png
csirt.cz	csirt.cz.png

以下命令将指导 convey 添加一个从主机名派生的电子邮件列,并且在发送文件时,将所有图片从路径列附加。

convey domains_images.csv  -t hostname,path -f abusemail --split abusemail --attach-files False  --attach-paths-from-path-column True

向导将引导您发送测试邮件到您自己的地址。这是针对 wikipedia.org 域的发送测试电子邮件对话框。

Attachment wikipedia.com.png (image/png): PNG...
MIME-Version: 1.0
Subject: PNG that might interest you
To: abuse@wikimedia.org
Date: Fri, 06 Jan 2023 20:04:31 +0100

Body text message
Testing e-mail address to be sent to – type in or hit Enter to use your-testing-mail@example.com (Ctrl+C to go back):

鸣谢

CSIRT.cz 提供。

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载您平台对应的文件。如果您不确定选择哪一个,请了解更多关于 安装包 的信息。

源分布

convey-1.4.4.tar.gz (167.8 kB 查看哈希值)

上传时间

构建分布

convey-1.4.4-py3-none-any.whl (157.9 kB 查看哈希值)

上传时间 Python 3

由以下支持