0
$cat file0
"basic/strong/bold"
" /""?basic""/strong/bold"
"^/))basic"
basic 

我想要 unix sed 命令,以便只更改不在引号中的基本命令。[将基本更改为环]

预期输出:

$cat file0
"basic/strong/bold"
" /""?basic""/strong/bold"
"^/))basic"
ring
4

5 回答 5

0
$> sed -r 's/^([^\"]*)(basic)([^\"]*)$/\1ring\3/' file0
"basic/strong/bold"
" /""?basic""/strong/bold"
"^/))basic"
ring

如果您想就地编辑文件,请使用--in-place选项。

于 2012-10-22T13:26:05.963 回答
0

如果我们不允许转义引号,basic则不在其中"的任何引号前面都有偶数个". 所以这应该可以解决问题:

sed -r 's/^([^"]*("[^"]*){2}*)basic/\1ring/' file

正如 ДМИТРИЙ МАЛИКОВ 所提到的,添加该--in-place选项将立即编辑文件,而不是返回新内容。

这是如何运作的?

我们将正则表达式锚定到每行的开头"。然后我们允许任意数量的非"字符(带有[^"]*)。然后我们开始一个"[^"]* 由一个"和任意多个非"字符组成的新子模式。我们重复偶数次(用{2}*)。然后我们匹配basicbasic因为我们在替换之前匹配了所有这些东西。这就是为什么这部分被包裹在另一对括号中,从而捕获该行并将其写回替换中,\1后跟ring.

一个警告:如果您basic在一行中有多次出现,这只会替换最后一个没有用双引号引起来的,因为正则表达式匹配不能重叠。一个解决方案将是一个lookbehind,但因为这将是一个可变长度的lookbehind,它仅受.NET regex 引擎支持。因此,如果您的实际输入是这种情况,请多次运行该命令,直到所有匹配项都被替换。

于 2012-10-22T17:19:56.620 回答
0

这可能对您有用(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
于 2012-10-22T19:07:18.750 回答
0

不是 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.

于 2012-10-26T03:54:14.873 回答
-3

如果 basic 位于行首:

sed -e 's/^basic/ring/' file0
于 2012-10-22T13:26:15.250 回答