2017-05-01 54 views
0

使用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寫入匹配左至右和捕獲一切正確的比賽?

回答

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}" 
2

的好消息是,你的替代已經是書面以「從左到右匹配並捕獲一切權利」!但是關於當前代碼無法正常工作,有兩點需要注意。

首先,您在括號中的組之前所要求的匹配是.*.匹配任何字符並且*匹配零次或多次出現次數。因此,該代碼匹配任何字符的零次或多次出現次數。但是有多少次出現是零或更多?

受到第二件事情的影響。默認情況下,匹配是貪婪的:它們匹配儘可能多的字符,而不會導致匹配失敗。在這種情況下,他們可以匹配的一切,直到最後下劃線

您可以修復你的模式匹配的單個字符(最終1前的一個。):.沒有*

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

某些工具允許使用minimal match,這會使匹配不太貪婪。但不是sed

1

echo「a_3_2_1」| SED -r 's/^(。*)/ \ 1 /'

SED正則表達式是 「貪婪」,這意味着他們總是匹配最長可能匹配。所以你的例子失敗了,因爲第一個.*_.*與之匹配之前佔用了所有的下劃線。