![如何使用‘sed’命令将匹配的模式保存到变量中?](https://linux22.com/image/864256/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E2%80%98sed%E2%80%99%E5%91%BD%E4%BB%A4%E5%B0%86%E5%8C%B9%E9%85%8D%E7%9A%84%E6%A8%A1%E5%BC%8F%E4%BF%9D%E5%AD%98%E5%88%B0%E5%8F%98%E9%87%8F%E4%B8%AD%EF%BC%9F.png)
我试图首先使用sed
命令来找到一种模式file.txt
字符1和字符2 然后用字符串替换它。像下面的echo
模式示例一样:
echo "This X is test Y. But X is not test Y." | sed 's/X[^Y]*Y/REPLACE/'
另外,我需要将匹配的模式(如is test
{<--spaces around is important} )保存在变量中。
答案1
这里是 sed 的一次调用,将修改后的行写入 stdout,同时将删除的文本保存在 shell 变量中var
:
$ var=$(echo "This X is test Y. But X is not test Y." | sed -nr 'h;s/[^X]*X([^Y]*)Y.*/\1/;p;x;s/X[^Y]*Y/REPLACE/;w /dev/stderr') 2>&1
This REPLACE. But X is not test Y.
的值为var
:
$ echo "==$var=="
== is test ==
解释:
h
此命令将当前模式复制到保持空间。
s/[^X]*X([^Y]*)Y.*/\1/;p
X
这将从模式空间中删除所有内容,除了第一个和之间的文本Y
(包括任何空格)。然后将其打印到 stdout。这是由 shell 捕获并分配给 的输出var
。x
这会将保留空间复制回模式空间。完成后,模式空间包含原始输入行的副本。
s/X[^Y]*Y/REPLACE/; w /dev/stderr
进行替换并将结果写入
stderr
。2>&1
在 shell 将 stdout 捕获到 之后
var
,这将指示 shell 将 stderr(包含 REPLACE 行)复制到 stdout。
除了处理变量var
变量var
包含前导空格和尾随空格。如果 shell 随后要var
进行分词,这些空格将被删除。为了防止这种情况,在var
引用时,请将其放在双引号内,如上例所示。
答案2
您必须使用第二个 sed 命令来完成此操作:
var=$(echo "This X is test Y. But X is not test Y." | \
tee >(sed 's/X[^Y]*Y/REPLACE/' >/dev/stderr) | \
sed -r 's/[^X]*X([^Y]*)Y.*/\1/')
说明:
- 您必须使用
tee
来分割流。它既包含字符串,stdout
又stderr
包含字符串。 tee
需要一个文件作为参数。我们给出tee
一个管道,用于sed
监听并替换字符串。sed
将字符串打印到stderr
:您在终端中看到的输出。- 第二条
sed
命令监听stdout
并提取所需的字符串,现在将其保存到变量中$var
(的内容stdout
)。
使用它来检查:
$ echo ">$var<"
> is test <