2016-03-27 12 views
0

revを使用せずに、行末からの正規表現の一致の最後のものから置き換えるために、sedまたはBashを使用するほうが簡単かどうか知りませんか?Ned Occurrenceを行の最後からSed経由で置き換える

rev最後に出現した文字「–」の3番目の文字と一致していますが、まだ最後の文字から一致するように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" 

注:それはLHSから正規表現のアイテムをエスケープする必要があり、真に汎用的であるために。 GNUで

+0

[編集ヘルプ](http://stackoverflow.com/editing-help)をご覧ください。 – Cyrus

答えて

0

はsedを:

sed -r 's/s(([^s]*s){2}[^s]*)$/S\1/' file 

出力:

 
a declaration of Sovereignty need no witness 

参照:The Stack Overflow Regular Expressions FAQ

+0

ありがとう、これは私が例として使用した一文字で動作しますが、正規表現 '[^ s]' - > '[^ importantword]'は期待どおりに一致しません。エンドアンカーをバックオフに合わせることは効果的なコンセプトです。 –

+0

'importantword'をマッチさせるには、最初にその単語をユニークな1文字に減らし、上記のようにマッチさせてから、変更されていない単語を元に戻します。 – potong

0

使用の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" 

出力:

a declaration of Sovereignty need no witness 
0

あなたはoccurancesの数をカウントし、交換するためにどちらを把握するために最初の必要性:

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/' 

または

str="\(.*importantword.*\)" 
echo "importantword1 importantword2 importantword3 importantword4 importantword5 importantword6" | 
    sed 's/\('${str}'\{'$l'\}\)importantword\('${str}'\{'$r'\}\)/\1ExportAntword\3/'