Bash 通过Sed替换行尾的第n个引用
您是否知道一种更好或更简单的方法,可以使用sed或Bash从一行末尾最后一次出现的正则表达式匹配中替换,而无需使用Bash 通过Sed替换行尾的第n个引用,bash,sed,Bash,Sed,您是否知道一种更好或更简单的方法,可以使用sed或Bash从一行末尾最后一次出现的正则表达式匹配中替换,而无需使用rev 下面是匹配字母“s”最后出现的第三个字母的rev方法–仍然是正向匹配,但利用rev匹配最后一个字符 echo "a declaration of sovereignty need no witness" | rev | sed 's/s/S/3' | rev a declaration of Sovereignty need no witness 更新——基于Cyruses
rev
下面是匹配字母“s”最后出现的第三个字母的rev
方法–仍然是正向匹配,但利用rev
匹配最后一个字符
echo "a declaration of sovereignty need no witness" | rev | sed 's/s/S/3' | rev
a declaration of Sovereignty need no witness
更新——基于Cyruses答案的通用解决方案:
SEARCH="one"
OCCURRENCE=3
REPLACE="FOUR"
SED_DELIM=$'\001'
SEARCHNEG=$(sed 's/./[^&]*/g' <<< "${SEARCH}")
sed -r "s${SED_DELIM}${SEARCH}((${SEARCHNEG}${SEARCH}){$((${OCCURRENCE}-1))}${SEARCHNEG})\$${SED_DELIM}${REPLACE}\1${SED_DELIM}" <<< "one one two two one one three three one one"
SEARCH=“一”
发生率=3
替换=“四个”
SED_DELIM=$'\001'
SEARCHNEG=$(sed's//[^&]*/g'与GNU sed:
sed -r 's/s(([^s]*s){2}[^s]*)$/S\1/' file
输出:
a declaration of Sovereignty need no witness
主权宣言不需要证人
请参阅:使用awk:
str='a declaration of sovereignty need no witness'
awk -v r='S' -v n=3 'BEGIN{FS=OFS="s"} {
for (i=1; i<=NF; i++) printf "%s%s", $i, (i<NF)?(i==NF-n?r:OFS):ORS}' <<< "$str"
您首先需要计算发生的事件数量,并确定要替换的事件:
echo "importantword1 importantword2 importantword3 importantword4 importantword5 importantword6" |
grep -o "importantword" | wc -l
将其用于sed字符串
echo "importantword1 importantword2 importantword3 importantword4 importantword5 importantword6" |
sed 's/\(\(.*importantword.*\)\{3\}\)importantword\(\(.*importantword.*\)\{2\}\)/\1ExportAntword\3/'
importantword1 importantword2 importantword3 ExportAntword4 importantword5 importantword6
通过设置左侧和右侧的变量,您可以得到相同的答案:
l=3
r=2
echo "importantword1 importantword2 importantword3 importantword4 importantword5 importantword6" |
sed 's/\(\(.*importantword.*\)\{'$l'\}\)importantword\(\(.*importantword.*\)\{'$r'\}\)/\1ExportAntword\3/'
或
在Perl中,可以使用前瞻断言:
echo "a declaration of sovereignty need no witness" \
| perl -pe 's/s(?=(?:[^s]*s[^s]*){2}$)/S/'
(?=…)
是前瞻性断言,它表示“如果后跟…”,但…部分不匹配,因此不被替换
[^s]*s[^s]*
表示只有一个s
可能由非s
es包装
{2}
是重复的次数,也就是说,我们希望在要替换的一个s之后有两个s
谢谢,这适用于我用作示例的单个字母,但适用于单词regex[^s]
-->[^importantword]
将无法按预期匹配。匹配结束锚是一个有效的概念。要匹配重要词汇,请首先将所述单词减少为唯一的单个字符,然后如上所述进行匹配,然后恢复未更改的单词。
str="\(.*importantword.*\)"
echo "importantword1 importantword2 importantword3 importantword4 importantword5 importantword6" |
sed 's/\('${str}'\{'$l'\}\)importantword\('${str}'\{'$r'\}\)/\1ExportAntword\3/'
echo "a declaration of sovereignty need no witness" \
| perl -pe 's/s(?=(?:[^s]*s[^s]*){2}$)/S/'