jpo*_*pou 5 regex shell pattern-matching
我在shell编程中完全迷失了,主要是因为我使用的每个站点都提供了不同的工具来进行模式匹配.所以我的问题是用什么工具在管道流中进行简单的模式匹配.
context:我有named.conf文件,我需要一个简单文件中的所有区域名称进行进一步处理.所以我做〜$ cat named.local | grep区域并在这里完全丢失.我输出的形式为'zone"domain.tld"{'的约100个换行符,我需要双引号文本.
感谢您展示了这样做的方法.
Ĵ
Sha*_*mer 23
我想,你要寻找的是sed......这是一个小号 tream 版 itor这将让你在一行接一行的基础上做的替代品.
正如您所解释的那样,命令`cat named.local | grep zone'给你一个像这样的输出:
zone "domain1.tld" {
zone "domain2.tld" {
zone "domain3.tld" {
zone "domain4.tld" {
Run Code Online (Sandbox Code Playgroud)
我猜你想要输出是这样的,因为你说你需要双引号文本:
"domain1.tld"
"domain2.tld"
"domain3.tld"
"domain4.tld"
Run Code Online (Sandbox Code Playgroud)
所以,实际上,从每一行我们只想要双引号之间的文本(包括双引号本身).
我不确定你是否熟悉正则表达式,但对于任何编写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
Run Code Online (Sandbox Code Playgroud)
进入这个列表:
The Kid
The Fish
The Man
Run Code Online (Sandbox Code Playgroud)
首先,你要在引号内查找字符串.我们已经看到了,它是/".*"/.
接下来,我们想要使用引号内的内容.我们可以使用parens对它进行分组:/"(.*)"/
如果我们想用引号替换带有下划线的文本,我们会做一个替换:s/"(.*)"/_/,这会让我们:
Billy _ Smith
Jimmy _ Stuart
Chuck _ Norris
Run Code Online (Sandbox Code Playgroud)
但我们有回溯!那将让我们回想一下使用符号的内部内容\1.所以如果我们现在这样做:s/"(.*)"/\1/我们会得到:
Billy The Kid Smith
Jimmy The Fish Stuart
Chuck The Man Norris
Run Code Online (Sandbox Code Playgroud)
因为引号不在parens中,所以它们不是内容的一部分\1!
要仅将内容留在双引号内,我们需要匹配整行.要做到这一点,我们有^(这意味着"行首")和$(这意味着"行尾".)
所以现在如果我们使用s/^.*"(.*)".*$/\1/,我们将获得:
The Kid
The Fish
The Man
Run Code Online (Sandbox Code Playgroud)
为什么?让我们s/^.*"(.*)".*$/\1/从左到右阅读正则表达式:
s/- 开始替换正则表达式^ - 寻找线的开头.从那里开始..* - 继续前进,阅读每一个角色,直到......" - ...直到你达到双重报价.( - 开始一组我们可能想要在回溯时回忆的字符..* - 继续前进,阅读每一个角色,直到......) - (pssst!关闭小组!)" - ...直到你达到双重报价..* - 继续前进,阅读每一个角色,直到......$ - 结束了!
/ - 使用之后的内容来替换您匹配的内容
\1 - 粘贴匹配的第一组(parens中的内容)的内容./ - 正则表达式结束用简单的英语:"读取整行,将文本复制到双引号之间.然后用双qoutes之间的内容替换整行."
你甚至可以在替换文本周围添加双引号s/^.*"(.*)".*$/"\1"/,这样我们就可以得到:
"The Kid"
"The Fish"
"The Man"
Run Code Online (Sandbox Code Playgroud)
这可以用来sed替换引号内的内容:
sed -e "s/^.*\"\(.*\)\".*$/\"\1\"/"
Run Code Online (Sandbox Code Playgroud)
(这只是shell转义处理双引号和斜线和东西.)
所以整个命令就像这样:
cat named.local | grep zone | sed -e "s/^.*\"\(.*\)\".*$/\"\1\"/"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15875 次 |
| 最近记录: |