因此,我们的想法是 使用文件中的 $SCL 变量nas_...
来替换匹配的模式,但排除 2 个不应该被替换的完全匹配nas_$SCL
nas_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_mba
和nas_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
(请注意,这假设您的序列做想要匹配由单词字符组成 - 如果不是这种情况,可以修改)。