我有一个包含很多条目的文件。我想提取某个组件的ID。该 ID 的前缀是abcd.inst 意味着只有一个词,就像
abcd.inst.sdt.gh-wer-1.anrg6ljrgo5rdtyc25lgtr2wf7iuhu2f5scwehpjjzerzpnphn3tzy4w2wjq
每当我这样做时
cat abcd.txt | grep "abcd.inst"
我得到的输出为
"id": "abcd.inst.sdt.gh-wer-1.anrg6ljrgo5rdtyc25lgtr2wf7iuhu2f5scwehpjjzerzpnphn3tzy4w2wjq"
无论如何,是否有可能将输出设为
abcd.inst.sdt.gh-wer-1.anrg6ljrgo5rdtyc25lgtr2wf7iuhu2f5scwehpjjzerzpnphn3tzy4w2wjq
我厌倦了使用
grep -oh abcd.inst abcd.txt
但输出是
abcd.inst
答案1
grep -o
将只输出匹配的文本,这就是为什么grep -o abcd.inst
只打印abcd.inst
.解决方案是使用正则表达式捕获整个输出。grep -oP 'abcd.inst[^"]+'
会做你想做的事。该-P
标志启用 Perl 样式模式,并且该模式已被修改以匹配下一个引号。这是一个链接一个能够准确解释该模式功能的工具。
答案2
如果文档是 JSON 文档,我们应该使用 JSON 解析器来解析它。在不知道id
在文档中哪里可以找到密钥的情况下这样做很尴尬,但也是可能的。下面,如果值以字符串 开头,我们将使用jq
从整个文档中的任何键中提取所有值。id
abcd.inst
jq -r ' .. |
select( type == "object" and
has("id") and
(.id | startswith("abcd.inst"))
).id' file.json
我们还可以将我们在命令行上查找的字符串传递给jq
.
jq -r --arg string 'abcd.inst' '
.. |
select( type == "object" and
has("id") and
(.id | startswith($string))
).id' file.json
如果我们将文档视为纯文本,我们可以使用它sed
来提取我们想要查找的字符串。这样做假设数据看起来像问题文本中的那样,并且与"id":
和"abcd.inst
子字符串在同一行上没有其他数据。我们还必须假设我们正在提取的字符串不包含嵌入的双引号,并且它不需要以任何方式编码进行解码。
sed -e '/^[[:blank:]]*"id":[[:blank:]]*"abcd\.inst/!d' \
-e 's/"[^"]*$//' \
-e 's/.*"//' file
上面的命令sed
删除文件中不以"id":
以下开头的任何行"abcd.inst
(在行的开头和两个指定的子字符串之间有可选的空格或制表符)。
随后的两次替换会修剪我们未按上述方式删除的行。第一次替换会删除该行的最后一个双引号及其后的所有内容。第二次替换将删除第一次替换所产生的行中从行开头到最后双引号的所有内容。
经过这些操作后,我们要查找的子字符串保留在该行中,并将sed
其输出到终端。