我正在办公室处理 Linux 系统上运行的一个问题。我希望能够使用 egrep 或 ksh 模式匹配来确定匹配的字符串,而且还需要能够确定匹配前和匹配后的字符串。
我知道我可以在 Perl 中做到这一点,但我还希望能够使用 egrep 或 ksh 模式匹配来做到这一点。
我进行了一些 Google 搜索,找到了一个 egrep 命令,您可以在其中指定预匹配和后匹配字符的数量,但这还不够好。我需要完整的预匹配和后匹配字符串。
答案1
和grep
你可以使用 Perl 的\K
(使用选项启用与 Perl 兼容的正则表达式-P
)和展望模式如下:
$ echo -e "pre1 line1 post1\npre2 line2 post2" |
grep -Po "pre2.*\Kline.(?=.*post2)"
line2
...其中查找和评估模式pre2.*
和但未包含在匹配输出中,但在输入行中相同序列中的所有三个模式成功匹配后,模式将打印在输出中。.*post2
line.
在 shell 中
在bash
以及 和其他类似的 Bourne 类 shell 中ksh
,zsh
您可以执行类似以下操作:
pat="line."
pre="pre2.*"
post=".*post2"
echo -e "pre1 line1 post1\npre2 line2 post2" |
while IFS= read -r line
do
[[ "$line" =~ $pre$pat$post ]] && echo "$line"
done
### Outputs "pre2 line2 post2"
### You can echo "$pat" as well
grep -Po
或者在文件上模拟上述输出,使用如下函数:
mygrep () {
pre="${1}.*"
pat="$2"
post=".*${3}"
file="$4"
help="Usage: mygrep \"prematch\" \"match\" \"postmatch\" \"filename\""
if [[ $# -lt 4 ]]
then
echo "$help"
return
fi
while IFS= read -r line
do
if [[ "$line" =~ $pre$pat$post ]]
then
for word in $line;
do
[[ "$word" =~ $pat ]] && echo "$word" && break
done
fi
done < "$file"
}
... 其工作原理如下:
$ cat file
pre1 line1 post2
pre2 someword line2 otherword post2
pre3 line3 nomatch post3
pre2 match match line4 will match post2
pre2 post2
pre2 nomatch post2
$
$
$ mygrep --help
Usage: mygrep "prematch" "match" "postmatch" "filename"
$
$
$ mygrep "pre2" "line." "post2" "./file"
line2
line4
注意$line
循环头部未加引号的参数for
是故意的,目的是允许 shell 进行单词拆分,以便可以循环遍历输入行中的单个单词,但要知道,如果该行中的一个单词恰好包含任何 glob 字符,这也将允许 shell 对当前工作目录中的文件名进行 globbing,因此在这种情况下,您可能需要首先读取单词 (按空格分割)将该行放入一个数组中并将它们作为数组元素进行循环,同时引用该数组元素的扩展……这将是更安全在这种情况下 (出于教育原因) ... 像这样:
mygrep () {
pre="${1}.*"
pat="$2"
post=".*${3}"
file="$4"
help="Usage: mygrep \"prematch\" \"match\" \"postmatch\" \"filename\""
if [[ $# -lt 4 ]]
then
echo "$help"
return
fi
while IFS=' ' read -r -a line
do
if [[ "${line[*]}" =~ $pre$pat$post ]]
then
for word in "${line[@]}";
do
[[ "$word" =~ $pat ]] && echo "$word" && break
done
fi
done < "$file"
}
注意另外,尽管 shell 可以使用 glob 模式或正则表达式模式来匹配文本,但这并不是最好的选择……请改用grep
或类似……不过,您可能想阅读可以使用 globbing 来搜索文件内容吗?