Sed:无法替换部分字符串而不替换全部
Sed: can not replace part of the string whithout replacing all of it
我正在尝试替换部分字符串,但找不到适合 sed 正确执行的正则表达式。
我有一个字符串
/abc/foo/../bar
我想达到以下结果:
/abc/bar
我试过使用这个命令来做到这一点:
echo $string | sed 's/\/[^:-]*\..\//\//'
但结果我只得到 /bar
。
我知道我必须使用组,但我就是不明白。
能否请您帮我找出可以使用的组?
你可以使用
#!/bin/bash
string='/abc/foo/../bar'
sed -nE 's~^(/[^/]*)(/.*)?/\.\.(/[^/]*).*~~p' <<< "$string"
参见online demo。 详情:
-n
- 抑制默认行输出
E
- 启用 POSIX ERE 正则表达式语法
^
- 字符串开头
(/[^/]*)
- 第 1 组:一个 /
然后 /
以外的零个或多个字符
(/.*)?
- 可选组 2:一个 /
然后是任何文本
/\.\.
- /..
固定字符串
(/[^/]*)
- 第 3 组:一个 /
然后 /
以外的零个或多个字符
.*
- 字符串的其余部分。
</code> 用第 1 组和第 3 组值连接替换匹配项</li>
<li><code>p
只打印替换成功的结果。
您可以对第一部分使用捕获组,然后匹配到最后 /
以删除。
当您使用 /
匹配模式时,您可以选择不同的分隔符。
#!/bin/bash
string="/abc/foo/../bar"
sed 's~\(/[^/]*/\)[^:-]*/~~' <<< "$string"
部分模式:
\(
捕获 组 1
/[^/]*/
从第一个到第二个 /
与中间 /
以外的任何字符匹配
\)
关闭组 1
[^:-]*/
匹配 :
和 -
以外的可选字符,然后匹配 /
输出
/abc/bar
使用 sed
$ sed 's#^\(/[^/]*\)/.*\(/\)##' input_file
/abc/bar
或
$ sed 's#[^/]*/[^/]*/##2' input_file
/abc/bar
使用 awk
string='/abc/foo/../bar'
awk -F/ '{print "/""/"$NF}' <<< "$string"
#or
awk -F/ 'BEGIN{OFS=FS}{print ,,$NF}' <<< "$string"
/abc/bar
使用bash
string='/abc/foo/../bar'
echo "${string%%/${string#*/*/}}/${string##*/}"
/abc/bar
使用任何 sed:
$ echo "$string" | sed 's:\(/[^/]*/\).*/::'
/abc/bar
我正在尝试替换部分字符串,但找不到适合 sed 正确执行的正则表达式。
我有一个字符串
/abc/foo/../bar
我想达到以下结果:
/abc/bar
我试过使用这个命令来做到这一点:
echo $string | sed 's/\/[^:-]*\..\//\//'
但结果我只得到 /bar
。
我知道我必须使用组,但我就是不明白。 能否请您帮我找出可以使用的组?
你可以使用
#!/bin/bash
string='/abc/foo/../bar'
sed -nE 's~^(/[^/]*)(/.*)?/\.\.(/[^/]*).*~~p' <<< "$string"
参见online demo。 详情:
-n
- 抑制默认行输出E
- 启用 POSIX ERE 正则表达式语法^
- 字符串开头(/[^/]*)
- 第 1 组:一个/
然后/
以外的零个或多个字符
(/.*)?
- 可选组 2:一个/
然后是任何文本/\.\.
-/..
固定字符串(/[^/]*)
- 第 3 组:一个/
然后/
以外的零个或多个字符
.*
- 字符串的其余部分。</code> 用第 1 组和第 3 组值连接替换匹配项</li> <li><code>p
只打印替换成功的结果。
您可以对第一部分使用捕获组,然后匹配到最后 /
以删除。
当您使用 /
匹配模式时,您可以选择不同的分隔符。
#!/bin/bash
string="/abc/foo/../bar"
sed 's~\(/[^/]*/\)[^:-]*/~~' <<< "$string"
部分模式:
\(
捕获 组 1/[^/]*/
从第一个到第二个/
与中间/
以外的任何字符匹配
\)
关闭组 1[^:-]*/
匹配:
和-
以外的可选字符,然后匹配/
输出
/abc/bar
使用 sed
$ sed 's#^\(/[^/]*\)/.*\(/\)##' input_file
/abc/bar
或
$ sed 's#[^/]*/[^/]*/##2' input_file
/abc/bar
使用 awk
string='/abc/foo/../bar'
awk -F/ '{print "/""/"$NF}' <<< "$string"
#or
awk -F/ 'BEGIN{OFS=FS}{print ,,$NF}' <<< "$string"
/abc/bar
使用bash
string='/abc/foo/../bar'
echo "${string%%/${string#*/*/}}/${string##*/}"
/abc/bar
使用任何 sed:
$ echo "$string" | sed 's:\(/[^/]*/\).*/::'
/abc/bar