sed从左到右对第一个字符进行替换

时间:2017-05-01 17:30:56

标签: bash sed

使用sed进行替换我希望匹配第一个字符,从左到右,以及匹配的所有内容。以下不起作用。

echo "a_4_3_2_1" | sed 's/.*\(_.*\)/\1/'  

echo "a_3_2_1" | sed 's/.*\(_.*\)/\1/'

两者仅输出_1

我希望输出为:_4_3_2_1_3_2_1

如何编写sed替换以从左到右匹配并捕获匹配的所有内容?

3 个答案:

答案 0 :(得分:4)

例如:

echo "a_4_3_2_1" | sed 's/[^_]*\(_.*\)/\1/'

 echo "a_4_3_2_1" | sed 's/[^_]*//'

echo "a_4_3_2_1" | grep -oP '^[^_]*\K.*'

在bash UUOE中 - 无用的回声。最好写:

grep -oP '^[^_]*\K.*' <<<"a_4_3_2_1"

完全跳过第一个字符:

grep -oP '^.\K.*' <<< "a_4_3_2_1"

 sed 's/.//' <<< "a_4_3_2_1"

bash

s="a_4_3_2_1"
echo "${s:1}"

答案 1 :(得分:2)

好消息是你的替换已被写入&#34;从左到右匹配并捕获匹配的所有内容&#34;!但是有两件事要记住你当前的代码无效。

首先,您在括号中的组之前所要求的匹配是.*.匹配任何字符,*匹配零次或多次匹配。因此代码匹配任何字符的零次或多次出现。但有多少次出现是零或多?

受第二件事的影响。默认情况下,匹配是贪婪的:它们匹配尽可能多的字符而不会导致匹配失败。在这种情况下,他们可以匹配最后一个下划线(最后一个1之前的那个)。

您可以修复您的模式以匹配单个字符:.而不是*

echo "a_4_3_2_1" | sed 's/.\(_.*\)/\1/'  
_4_3_2_1

某些工具允许使用minimal match,这会使匹配变得非贪婪。但不是sed

答案 2 :(得分:1)

回声&#34; a_3_2_1&#34; | sed -r&#39; s / ^。(。*)/ \ 1 /&#39;

sed regexes&#34; greedy&#34;意味着他们总是匹配最长的匹配。因此,您的示例会失败,因为第一个.*会在_.*匹配它们之前占用所有下划线。