Regex Bash-grep提取以指定字符串结尾的单词;在找不到匹配项的地方留下空白
以下是输入数据: I/o live/o in/o New/B-geo-loc York/I-geo-locRegex Bash-grep提取以指定字符串结尾的单词;在找不到匹配项的地方留下空白,regex,bash,algorithm,text,grep,Regex,Bash,Algorithm,Text,Grep,以下是输入数据: I/o live/o in/o New/B-geo-loc York/I-geo-loc I/o活动/o某处/o在/o空间/o I/o will/o love/o to/o live/o在法国/B-geo-loc 此/o为/o我的/o主页/o 旧金山/B-geo-loc CA/I-geo-loc为/o a/o伟大/o场所/o至/o现场/o 其目的是提取以“/B-geo-loc”或“/I-geo-loc”结尾的所有单词,并在未找到匹配项的地方留下空行 尝试在grep中使用以下正则
I/o活动/o某处/o在/o空间/o
I/o will/o love/o to/o live/o在法国/B-geo-loc
此/o为/o我的/o主页/o
旧金山/B-geo-loc CA/I-geo-loc为/o a/o伟大/o场所/o至/o现场/o 其目的是提取以“
/B-geo-loc
”或“/I-geo-loc
”结尾的所有单词,并在未找到匹配项的地方留下空行
尝试在grep中使用以下正则表达式,但未获得所需的输出
grep -o '\w*/B-geo-loc\b \w*/I-geo-loc\b' sourcefile.txt > targetfile.txt
这是我的正则表达式输出:
纽约/B-geo-loc纽约/I-geo-loc旧金山/B-geo-loc CA/I-geo-loc 代替此所需输出: 纽约/B-geo-loc纽约/I-geo-loc
---空行--
法国/B-geo-loc
---空行--
旧金山/B-geo-loc CA/I-geo-loc
谢谢。这里没有真正的义务使用
grep
,如果它不能满足您的需要。以下是在本机bash中实现的(不是POSIX sh——如果将其嵌入脚本中,则使用#!/bin/bash
shebang,而不是#!/bin/sh
one):
读-r-a字时;做
匹配项=()
用于“${words[@]}”中的单词;做
[[$word=*/[IB]-geo-loc]]&&matches+=(“$word”)
完成
printf'%s\n'${matches[*]}
完成targetfile.txt
对于一个庞大的输入文件,使用ksh93或awk可能值得重写,这两种文件的性能都比bash好,但如果你不花大量的时间坐在那里等待它运行,那就没什么关系了。如果它不能满足你的要求,那么这里就没有真正的义务使用
grep
。以下是在本机bash中实现的(不是POSIX sh——如果将其嵌入脚本中,则使用#!/bin/bash
shebang,而不是#!/bin/sh
one):
$ awk '{c=0; for (i=1;i<=NF;i++) if ($i ~ /\/[BI]-geo-loc$/) printf "%s%s", (c++ ? OFS : ""), $i; print ""}' file
New/B-geo-loc York/I-geo-loc
France/B-geo-loc
Sanfrancisco/B-geo-loc CA/I-geo-loc
读-r-a字时;做
匹配项=()
用于“${words[@]}”中的单词;做
[[$word=*/[IB]-geo-loc]]&&matches+=(“$word”)
完成
printf'%s\n'${matches[*]}
完成targetfile.txt
对于一个庞大的输入文件,使用ksh93或awk可能值得重新编写,这两种文件的性能都比bash好,但如果你没有花大量的时间坐在那里等待它运行,那就没什么关系了。$awk'{c=0;for(i=1;i$awk'{c=0;for(i=1;i
$ awk '{c=0; for (i=1;i<=NF;i++) if ($i ~ /\/[BI]-geo-loc$/) printf "%s%s", (c++ ? OFS : ""), $i; print ""}' file
New/B-geo-loc York/I-geo-loc
France/B-geo-loc
Sanfrancisco/B-geo-loc CA/I-geo-loc
m#\w+/B-geo-loc |\w+/I-geo-loc#g
提供所有匹配项,m
允许使用/
以外的其他字符作为分隔符
- 也可以使用
m#\w+/(?:B-geo-loc | I-geo-loc)#g
或m#\w+/[IB]-geo-loc#g
print join”“,
使用空格作为分隔符来打印匹配项
m#\w+/B-geo-loc |\w+/I-geo-loc#g
提供所有匹配项,m
允许使用/
以外的其他字符作为分隔符
- 也可以使用
m#\w+/(?:B-geo-loc | I-geo-loc)#g
或m#\w+/[IB]-geo-loc#g
print join”“,
使用空格作为分隔符来打印匹配项
顺便说一句,POSIX不能保证grep支持\w
或\b
,因为BRE或ERE中都没有规定;因此从可移植性的角度来看,不依赖它们更安全。顺便说一句,POSIX不能保证\w
或\b
会得到grep的支持,因为两者都不受支持其中一个是在BRE或ERE中指定的;因此,从可移植性的角度来看,不依赖它们更安全。您的答案启发我修改我的答案,以消除尾随空格——基于性能的awk答案并不令人羞耻,但我不希望在正确性方面落后于任何人。:)@Ed Morton我在运行awk脚本awk时遇到以下错误:1:意外字符“.”Thanks@Seanclick然后,您没有执行我发布的脚本,在看不到您正在运行的内容的情况下,我无法帮助您诊断该错误消息。请确保复制/粘贴脚本,不要尝试重新键入它。@Ed Morton这太糟糕了!工作得很好ly…显然,我在执行脚本时有一点输入错误…复制/粘贴效果很好..谢谢你的答案启发我修改我的答案,以消除尾随的空白--基于性能的awk答案并不丢脸,但我不想在正确性方面落后于任何人。:)@Ed Morton我在运行awk脚本awk时遇到以下错误:1:意外字符“.”Thanks@Seanclick然后,您没有执行我发布的脚本,在看不到您正在运行的内容的情况下,我无法帮助您诊断该错误消息。请确保复制/粘贴脚本,不要尝试重新键入它。@Ed Morton这太糟糕了!工作得很好很明显,我在执行脚本时有一个轻微的输入错误…复制/粘贴工作很好…谢谢
$ cat ip.txt
I/o live/o in/o New/B-geo-loc York/I-geo-loc
I/o live/o somewhere/o in/o space/o
I/o would/o love/o to/o live/o in France/B-geo-loc
This/o is/o my/o home/o
Sanfrancisco/B-geo-loc CA/I-geo-loc is/o a/o great/o place/o to/o live/o
$ perl -lne 'print join " ", m#\w+/B-geo-loc|\w+/I-geo-loc#g' ip.txt
New/B-geo-loc York/I-geo-loc
France/B-geo-loc
Sanfrancisco/B-geo-loc CA/I-geo-loc