所以我有一个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