$cat file0
"basic/strong/bold"
" /""?basic""/strong/bold"
"^/))basic"
basic
我想要 unix sed 命令,以便只更改不在引号中的基本命令。[将基本更改为环]
预期输出:
$cat file0
"basic/strong/bold"
" /""?basic""/strong/bold"
"^/))basic"
ring
$> sed -r 's/^([^\"]*)(basic)([^\"]*)$/\1ring\3/' file0
"basic/strong/bold"
" /""?basic""/strong/bold"
"^/))basic"
ring
如果您想就地编辑文件,请使用--in-place
选项。
如果我们不允许转义引号,basic
则不在其中"
的任何引号前面都有偶数个"
. 所以这应该可以解决问题:
sed -r 's/^([^"]*("[^"]*){2}*)basic/\1ring/' file
正如 ДМИТРИЙ МАЛИКОВ 所提到的,添加该--in-place
选项将立即编辑文件,而不是返回新内容。
这是如何运作的?
我们将正则表达式锚定到每行的开头"
。然后我们允许任意数量的非"
字符(带有[^"]*
)。然后我们开始一个"[^"]*
由一个"
和任意多个非"
字符组成的新子模式。我们重复偶数次(用{2}*
)。然后我们匹配basic
。basic
因为我们在替换之前匹配了所有这些东西。这就是为什么这部分被包裹在另一对括号中,从而捕获该行并将其写回替换中,\1
后跟ring
.
一个警告:如果您basic
在一行中有多次出现,这只会替换最后一个没有用双引号引起来的,因为正则表达式匹配不能重叠。一个解决方案将是一个lookbehind,但因为这将是一个可变长度的lookbehind,它仅受.NET regex 引擎支持。因此,如果您的实际输入是这种情况,请多次运行该命令,直到所有匹配项都被替换。
这可能对您有用(GNU sed):
sed -r 's/^/\n/;ta;:a;s/\n$//;t;s/\n("[^"]*")/\1\n/;ta;s/\nbasic/ring\n/;ta;s/\n([^"]*)/\1\n/;ta' file
不是 sed 解决方案,但它会替换不在引号中的单词
假设字符串中没有转义引号,即"This is a trap \" hehe"
awk 或许可以解决这个问题
awk -F\" 'BEGIN {OFS=FS}
{
for(i=1; i<=NF; i++){
if(i%2)
gsub(/basic/,"ring",$i)
}
print
}' inputFile
基本上不在引号中的单词在奇数字段中,并且在这些字段中将单词“basic”替换为“ring”。
This can be written as a one-liner, but for clarity's sake I've written it in multiple lines.
如果 basic 位于行首:
sed -e 's/^basic/ring/' file0