搜索、分离和清除 txt 值

bnd*_*iok 5 grep awk json

真正让我感到困惑的是引号。

我有一个file.txt像这样的行:

{"a":"town, state, country","e":["john@company.com"],"n":"john smith"}
{"a":"town, state, country","e":["zac@company.com","zacsurname@gmail.com"],"n":"zac surname"}
{"a":"town, state, country","n":"jane doe"}
Run Code Online (Sandbox Code Playgroud)

我只在寻找名字和电子邮件,并丢弃没有两者的数据。所以output.txt上面的 3 行应该是:

john john@company.com
zac zac@company.com
zac zacsurname@gmail.com
Run Code Online (Sandbox Code Playgroud)

我试过 awk、nawk、pcregrep、sed、perl,例如:

awk -F ":" '$1 ~ /^e/ && $1 ~ /^n/ { print $1,$1 }' file.txt > output.txt
awk -F "\"e\":\"" '{ print $1}' file.txt > output.txt
nawk '/\"e\":[\"/, /\"]/' file.txt > output.txt
pcregrep -o '(?<=[\").*?(?=\"])' <<< file.txt > output.txt
Run Code Online (Sandbox Code Playgroud)

它都不起作用。感谢您的帮助。

Kus*_*nda 10

由于您的文件是 JSON 文档,因此使用 JSON 解析器(例如jq)来解析它是最有意义的:

jq -r '
    select(has("n") and has("e")) |
    (.n|split(" ")[0]) as $name |
    .e[] | [ $name, . ] | @tsv' file.txt
Run Code Online (Sandbox Code Playgroud)

这将从您的一组对象中选择所有对象,这些对象同时具有 an和一个e键,并丢弃其余对象。

对于每个选定的对象,n键的值在空格上进行分割,并将第一个生成的单词分配给内部变量$name

然后我们遍历e数组的元素并使用$name值和元素(电子邮件地址)创建数组。这些数组中的每一个都提供给@tsv操作员,操作员将数据输出为两个字段的制表符分隔列表。

结果将是

john    john@company.com
zac     zac@company.com
zac     zacsurname@gmail.com
Run Code Online (Sandbox Code Playgroud)

感兴趣的读者请注意:我将其扩展为仅提取与文件中允许的名称列表匹配的第一个名称的条目。请参阅我对文件中一行的第一个单词的 Grep 的回答