sed:从匹配模式中排除几个部分字符串

sed:从匹配模式中排除几个部分字符串

因此,我们的想法是 使用文件中的 $SCL 变量nas_...来替换匹配的模式,但排除 2 个不应该被替换的完全匹配nas_$SCLnas_mba && nas_tvr

到目前为止,我的代码排除了这两个匹配项,但也干扰了其他不需要的匹配项

sed -i "s/nas_[^mt][^bv][^ar]/nas_$SCL/gI" filename.xml

如何仅排除这 2 个完全匹配的内容?

更新:到目前为止我已经找到了下一个解决方案

sed -i "/(nas_mba|nas_tvr)/! s/nas_.../nas_$SCL/"

但如果有匹配它会跳过整行

答案1

我将这样做:

sed -E '/(nas_mba|nas_tvr)/! s/nas_.../nas_bar/'

例子:

echo "nas_mba
nas_tvr
nas_foo" | sed -E '/(nas_mba|nas_tvr)/! s/nas_.../nas_bar/'
nas_mba
nas_tvr
nas_bar

nas_foo替换了原文,而nas_mbanas_tvr均保持不变。

另一个有更多行的例子:

echo "nas_hat
> nas_mba
> nas_foo
> nas_hat
> nat_tvr
> nas_cat
> nas_dog" | sed -E '/(nas_mba|nas_tvr)/! s/nas_.../nas_bar/'
nas_bar
nas_mba
nas_bar
nas_bar
nat_tvr
nas_bar
nas_bar

如果您想就地更改,只需添加该-i选项(如果您使用 GNU,sed则不需要,-i ""只需添加-i就足够了):

sed -E -i "" '/(nas_mba|nas_tvr)/! s/nas_.../nas_bar/' nas.txt 
cat nas.txt 
nas_bar
nas_mba
nas_bar
nas_bar
nat_tvr
nas_bar
nas_bar

在 Mac OS X 10.11.6 和 BSD 下测试sed

答案2

如果 perl 是一个选项,你可以使用展望

export SCL
perl -pe 's/nas_(?!mba|tvr)\w*/nas_$ENV{SCL}/g' file

(请注意,这假设您的序列想要匹配由单词字符组成 - 如果不是这种情况,可以修改)。

相关内容