匹配并打印与长字符串中的某个模式匹配的所有单词
Match and print all words matching some pattern in a long string
我的文本文件有以下几行(实际上更长):
U-what's-WORD|C U--PW|C U-you-NW|C U-what's--W-PW|C U-PROGRAM-GAZ|C
U-timothy-WORD|C U--PW|C U-green-NW|C U-timothy--W-PW|C
U-life-WORD|C U-odd-PW|C U--NW|C U-life-odd-W-PW|C
U-green-PW|C U-life-NW|C U-PROGRAM-GAZ|C U-odd-green-W-PW|C
U-green-xxxxk-DISJP-CS|C U-timothy-xxxxk-DISJP-CS|C U-PROGRAM-GAZ1|C U-PROGRAM-GAZ|C
我想打印所有只包含“GAZ”的单词。如果一行不包含任何这样的词,则打印空行。
我尝试使用 grep 进行搜索,但它匹配并打印了整行。我尝试在 sed 中使用带有边界的捕获组 (\b.P.\b) 并打印该组 \1 无济于事。
编辑
一种直接的方法(我还不想实现)是编写 python 脚本。该脚本将逐行运行:
- 使用空格分隔符对字符串进行标记
- 将每个标记与模式 P 匹配,如果匹配则打印它
- 如果整行都没有匹配,就打印空行
这将打印一行中与模式 P
匹配的任何单词。如果没有找到单词,则打印一个空行:
$ awk -v P=GAZ '{for (i=1;i<=NF;i++) if($i~P)printf "%s ",$i; print ""}' file
U-PROGRAM-GAZ|C
U-PROGRAM-GAZ|C
U-PROGRAM-GAZ1|C U-PROGRAM-GAZ|C
工作原理
-v P=GAZ
这定义了模式 P
。 P
可能是正则表达式。
for (i=1;i<=NF;i++) if ($i ~ P) printf "%s ",$i
循环遍历行中的每个单词。如果该词匹配模式 P
(P
可能是正则表达式),则打印该词。
print ""
在每行的末尾,无论是否匹配,都会打印一个换行符。
我假设 "word" 是一个非空白序列。这里的关键是 grep 的 -o
选项,它只打印正则表达式匹配的内容,而不是整行。
while IFS= read -r line; do
grep -oP '\S*GAZ\S*' <<< "$line" | tr '\n' ' '
echo
done < file
U-PROGRAM-GAZ|C
U-PROGRAM-GAZ|C
U-PROGRAM-GAZ1|C U-PROGRAM-GAZ|C
sed 's/.*/ & /;s/ / /g;s/GAZ/³/g;s/ [^ ³]\{1,\} / /g;s/³/GAZ/g;s/ */ /;s/.\(.*\).//' YourFile
- 对于 posix sed(没有 不是这个组 可用的正则表达式)
- 假设字符串中没有
³
(可以使用其他临时字符或添加转义序列,有点重)
原则:
- 删除线上没有 GAZ 的组
- 因为 GAZ 不能作为排除选择,将
GAZ
替换为 ³
并排除 ³
这是一个单一的 univoq char class 排除,放回 GAZ
之后。
- 调整字符串以便于选择(在开头和结尾添加一个 space,双 space)并在结尾重新格式化
我的文本文件有以下几行(实际上更长):
U-what's-WORD|C U--PW|C U-you-NW|C U-what's--W-PW|C U-PROGRAM-GAZ|C
U-timothy-WORD|C U--PW|C U-green-NW|C U-timothy--W-PW|C
U-life-WORD|C U-odd-PW|C U--NW|C U-life-odd-W-PW|C
U-green-PW|C U-life-NW|C U-PROGRAM-GAZ|C U-odd-green-W-PW|C
U-green-xxxxk-DISJP-CS|C U-timothy-xxxxk-DISJP-CS|C U-PROGRAM-GAZ1|C U-PROGRAM-GAZ|C
我想打印所有只包含“GAZ”的单词。如果一行不包含任何这样的词,则打印空行。
我尝试使用 grep 进行搜索,但它匹配并打印了整行。我尝试在 sed 中使用带有边界的捕获组 (\b.P.\b) 并打印该组 \1 无济于事。
编辑 一种直接的方法(我还不想实现)是编写 python 脚本。该脚本将逐行运行:
- 使用空格分隔符对字符串进行标记
- 将每个标记与模式 P 匹配,如果匹配则打印它
- 如果整行都没有匹配,就打印空行
这将打印一行中与模式 P
匹配的任何单词。如果没有找到单词,则打印一个空行:
$ awk -v P=GAZ '{for (i=1;i<=NF;i++) if($i~P)printf "%s ",$i; print ""}' file
U-PROGRAM-GAZ|C
U-PROGRAM-GAZ|C
U-PROGRAM-GAZ1|C U-PROGRAM-GAZ|C
工作原理
-v P=GAZ
这定义了模式
P
。P
可能是正则表达式。for (i=1;i<=NF;i++) if ($i ~ P) printf "%s ",$i
循环遍历行中的每个单词。如果该词匹配模式
P
(P
可能是正则表达式),则打印该词。print ""
在每行的末尾,无论是否匹配,都会打印一个换行符。
我假设 "word" 是一个非空白序列。这里的关键是 grep 的 -o
选项,它只打印正则表达式匹配的内容,而不是整行。
while IFS= read -r line; do
grep -oP '\S*GAZ\S*' <<< "$line" | tr '\n' ' '
echo
done < file
U-PROGRAM-GAZ|C
U-PROGRAM-GAZ|C
U-PROGRAM-GAZ1|C U-PROGRAM-GAZ|C
sed 's/.*/ & /;s/ / /g;s/GAZ/³/g;s/ [^ ³]\{1,\} / /g;s/³/GAZ/g;s/ */ /;s/.\(.*\).//' YourFile
- 对于 posix sed(没有 不是这个组 可用的正则表达式)
- 假设字符串中没有
³
(可以使用其他临时字符或添加转义序列,有点重)
原则:
- 删除线上没有 GAZ 的组
- 因为 GAZ 不能作为排除选择,将
GAZ
替换为³
并排除³
这是一个单一的 univoq char class 排除,放回GAZ
之后。 - 调整字符串以便于选择(在开头和结尾添加一个 space,双 space)并在结尾重新格式化