Grep 文件中一行的第一个单词

Grep 文件中一行的第一个单词

所以我有一个file.txt喜欢

John [email protected]
Mary [email protected]

但我也有

Pickethunter123 [email protected]
XPC61 [email protected]
GeorgeBushSucks [email protected]

我有一份英文名字清单names.txt。有没有办法仅通过行的第一个单词对另一个文件进行 grep ?

答案1

如果您希望正则表达式仅在模式的开头匹配,则可以将行锚点添加^到文件的每一行names.txt。如果您不想就地修改文件,您可以使用以下命令即时执行此sed操作:

sed 's/^/^/' names.txt | grep -wf - file.txt

将结果传递给grep -f标准输入-

或者,对于分隔数据,awk 是一个不错的选择:

awk 'NR==FNR{fn[$1]; next} $1 in fn' names.txt file.txt

答案2

将此连接到你的以前的问题,其中您有一个包含内容的 JSON 文档

{"a":"town, state, country","e":["[email protected]"],"n":"john smith"}
{"a":"town, state, country","e":["[email protected]","[email protected]"],"n":"zac surname"}
{"a":"town, state, country","n":"jane doe"}

要提取第一个名称的列表(每个n键值中第一个空格字符之前的值)以及e值中的电子邮件地址,我建议您使用jq并执行

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

(看我之前的回答有关此命令的简要说明)。

我们可以修改它以包含读取有效名称列表:

jq -Rs 'rtrimstr("\n") | split("\n") | map(ascii_upcase)' names.txt |
jq -r '
    . as $valid_names |
    inputs | select(has("n") and has("e")) |
    (.n|split(" ")[0]) as $name | select(($name | ascii_upcase) == $valid_names[]) |
    .e[] | [ $name, . ] | @tsv' - file.txt

这会调用jq两次。第一个调用是将names.txt名称列表(假设每行一个名称)转换为大写字符串的 JSON 数组。

例如,如果我们的names.txt文件包含

marty
zac

那么第一次jq调用将生成 JSON 文档

[
  "MARTY",
  "ZAC"
]

第二次调用从读取第一个调用开始,从大写名称列表jq创建集合。$valid_names

然后,该inputs函数用于从 中file.txt逐一读取 JSON 对象,其余部分与我之前给您的回答中的内容非常相似,只是我们通过额外的操作将数据限制select为只有第一个名称匹配的条目集合中的一个名字$valid_names

使用names.txt上面示例中的文件以及file.txt本答案顶部的文件,输出将是单行

zac     [email protected]
zac     [email protected]

答案3

您可以使用 转换文件cut,然后将其通过管道传输到您的grep命令中:

cut -d' ' -f1 file.txt | grep -F -f names.txt

相关内容