gpt4 book ai didi

regex - 匹配引号中的文本(新手)

转载 作者:行者123 更新时间:2023-12-04 16:20:03 27 4
gpt4 key购买 nike

我完全迷失在 shell 编程中,主要是因为我使用的每个站点都提供不同的工具来进行模式匹配。所以我的问题是使用什么工具在管道流中进行简单的模式匹配。

上下文:我有named.conf 文件,我需要一个简单文件中的所有区域名称以供进一步处理。所以我做 ~$ cat named.local | grep zone 并在这里完全迷路。我的输出是 'zone "domain.tld"{' 形式的大约一百个换行符,我需要双引号中的文本。

感谢您展示一种方法来做到这一点。

J

最佳答案

我想你要找的是 sed ... 这是一个 s 编辑 itor 可以让您逐行进行替换。

正如你所解释的,命令`cat named.local | grep zone' 给你一个类似这样的输出:

zone "domain1.tld" {
zone "domain2.tld" {
zone "domain3.tld" {
zone "domain4.tld" {

我猜你希望输出是这样的,因为你说你需要双引号中的文本:
"domain1.tld"
"domain2.tld"
"domain3.tld"
"domain4.tld"

所以,实际上,从每一行开始,我们只想要双引号之间的文本(包括双引号本身)。

我不确定您是否熟悉 Regular Expressions ,但对于任何编写 shell 脚本的人来说,它们都是一个非常宝贵的工具。例如,正则表达式 /.o.e/将匹配任何带有第二个字母的单词的行是小写 o ,第四个是 e .这将匹配包含“ zone”、“ tone”或“ I am tone-deaf.”等单词的字符串

诀窍是使用 . (点)字符表示“任何字母”。还有一些其他特殊字符,例如 *这意味着“重复前一个字符 0 次或更多次”。因此,像 a* 这样的正则表达式将匹配“ a”、“ aaaaaaa”或空字符串:“”

因此,您可以使用以下方法匹配引号内的字符串: /".*"/
关于 sed,您还需要了解另一件事(根据评论,您已经这样做了!) - 它允许回溯。一旦你告诉它如何识别一个词,你就可以让它使用这个词作为替换的一部分。例如,假设您想翻转此列表:
Billy "The Kid" Smith
Jimmy "The Fish" Stuart
Chuck "The Man" Norris

进入这个列表:
The Kid
The Fish
The Man

首先,您要查找引号内的字符串。我们已经看到了,它是 /".*"/ .

接下来,我们要使用引号内的内容。我们可以使用括号对其进行分组: /"(.*)"/
如果我们想用带下划线的引号替换文本,我们会做一个替换: s/"(.*)"/_/ ,这会给我们留下:
Billy _ Smith
Jimmy _ Stuart
Chuck _ Norris

但我们有回溯!这将让我们使用符号 \1 来记忆括号内的内容。 .所以如果我们现在这样做: s/"(.*)"/\1/我们会得到:
Billy The Kid Smith
Jimmy The Fish Stuart
Chuck The Man Norris

因为引号不在括号中,所以它们不是 \1 内容的一部分。 !

为了只保留双引号内的内容,我们需要匹配整行。为此,我们有 ^ (意思是“行首”)和 $ (这意味着“行尾”。)

所以现在如果我们使用 s/^.*"(.*)".*$/\1/ ,我们会得到:
The Kid
The Fish
The Man

为什么?让我们阅读正则表达式 s/^.*"(.*)".*$/\1/从左到右:
  • s/ - 开始 替代正则表达式
  • ^ - 寻找行的开头。从那里开始。
  • .* - 继续阅读每个字符,直到...
  • " - ... 直到出现双引号。
  • ( - 开始一组一个我们可能想在回溯时记忆的字符。
  • .* - 继续阅读每个字符,直到...
  • ) - (嘘!关闭群!)
  • " - ... 直到出现双引号。
  • .* - 继续阅读每个字符,直到...
  • $ - 行的尽头!
  • / - 使用此后的内容替换您匹配的内容
  • \1 - 粘贴第一组的内容(括号中的内容)匹配。
  • / - 正则表达式结束

  • 用简单的英语:“阅读整行,将双引号之间的文本复制到一边。然后用双引号之间的内容替换整行。”

    您甚至可以在替换文本周围添加双引号 s/^.*"(.*)".*$/"\1"/ ,所以我们会得到:
    "The Kid"
    "The Fish"
    "The Man"

    并且可以由 sed 使用用引号内的内容替换该行:
    sed -e "s/^.*\"\(.*\)\".*$/\"\1\"/"

    (这只是 shell 转义来处理双引号和斜杠之类的东西。)

    所以整个命令将类似于:
    cat named.local | grep zone | sed -e "s/^.*\"\(.*\)\".*$/\"\1\"/"

    关于regex - 匹配引号中的文本(新手),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/792474/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com