替换单词不是双引号

时间:2012-10-22 13:19:33

标签: regex sed

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

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

预期产出:

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

5 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

如果我们禁止转义引号,那么不在basic范围内的任何"前面会有偶数"。所以这应该可以解决问题:

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

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

这是如何运作的?

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

有一点需要注意:如果一行中有多个basic次出现,这只会替换未用双引号括起来的最后一个,因为正则表达式匹配不能重叠。一个解决方案将是一个后视,但由于这将是一个可变长度的lookbehind,只有.NET正则表达式引擎支持。因此,如果在实际输入中就是这种情况,请多次运行该命令,直到所有匹配项都被替换为止。

答案 2 :(得分: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

答案 3 :(得分: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

基本上,不在引号中的单词在奇数字段中,而单词&#34; basic&#34;被&#34; ring&#34;取代在这些领域。

这可以写成一个单行,但为了清楚起见,我已经用多行写了。

答案 4 :(得分:-3)

如果基本位于行的开头:

sed -e 's/^basic/ring/' file0