如何替换除感兴趣的字符串之外的所有内容

时间:2015-10-02 22:39:44

标签: regex bash awk sed

file.txt的

fruits:banana,apple,grape,limon,orange,tomate,
fruits:apple,limon,
fruits:banana,grape,limon,
fruits:orange,tomate,grape,
fruits:banana,
fruits:apple,
fruits:banana,apple,

我需要为FRUIT更换与“banana”不同的所有内容,并获得如下输出:

fruits:banana,FRUIT,FRUIT,FRUIT,FRUIT,FRUIT,
fruits:FRUIT,FRUIT,
fruits:banana,FRUIT,FRUIT,
fruits:FRUIT,FRUIT,FRUIT,
fruits:banana,
fruits:FRUIT,
fruits:FRUIT,apple,

我尝试使用awk,但我只能替换特定字符串的字段。

示例用fruit2替换所有字符串“apple”,或者用fruit2替换所有字符串“apple”,用fruit3替换所有字符串“tomate”或“orange”

awk -F":" '{ gsub(/apple/,"FRUIT2",$2); print }' OFS="," file.tx

awk -F":" '{ gsub(/apple/,"FRUIT2",$2);;gsub(/tomate|orange/,"FRUIT3",$2); print }' OFS="," file.txt |sed "s/./:/7"

fruits:banana,FRUIT2,grape,limon,FRUIT3,FRUIT3,
fruits:FRUIT2,limon,
fruits:banana,grape,limon,
fruits:FRUIT3,FRUIT3,grape,
fruits:banana,
fruits:FRUIT2,
fruits:banana,FRUIT2

但我真的需要更换与任何字符串不同的所有内容,例如:fruit4

如何生成这样的输出?

fruits:FRUIT4,FRUIT2,FRUIT4,FRUIT4,FRUIT3,FRUIT3,
fruits:FRUIT2,FRUIT4,
fruits:FRUIT4,FRUIT4,FRUIT4,
fruits:FRUIT3,FRUIT3,FRUIT4,
fruits:FRUIT4,
fruits:FRUIT2,
fruits:FRUIT4,FRUIT2

3 个答案:

答案 0 :(得分:1)

这个awk应该可以工作:

awk -F, -v OFS=, '{
   for (i=1; i<=NF; i++)
     if ($i !~ /(^|:)banana$/)
        sub(/[^:]+$/, "FRUIT", $i)
} 1' file

<强>输出:

fruits:banana,FRUIT,FRUIT,FRUIT,FRUIT,FRUIT,
fruits:FRUIT,FRUIT,
fruits:banana,FRUIT,FRUIT,
fruits:FRUIT,FRUIT,FRUIT,
fruits:banana,
fruits:FRUIT,
fruits:banana,FRUIT,

答案 1 :(得分:1)

要使流程自动化,您可以

awk -F '[:,]' -v OFS=, '
    {
        for (i=2; i<=NF; i++) 
            if ($i)
                if (seen[$i])
                    $i = seen[$i]
                else 
                    $i = seen[$i] = "FRUIT" ++n
        sub(OFS, ":")
        print
    }
    END {
        print "map:"
        for (key in seen)
            print key "\t" seen[key]
    }
' file
fruits:FRUIT1,FRUIT2,FRUIT3,FRUIT4,FRUIT5,FRUIT6,
fruits:FRUIT2,FRUIT4,
fruits:FRUIT1,FRUIT3,FRUIT4,
fruits:FRUIT5,FRUIT6,FRUIT3,
fruits:FRUIT1,
fruits:FRUIT2,
fruits:FRUIT1,FRUIT2,
map:
orange  FRUIT5
tomate  FRUIT6
apple   FRUIT2
limon   FRUIT4
banana  FRUIT1
grape   FRUIT3

答案 2 :(得分:0)

如果您希望能够灵活地在命令行上指定旧名称到新名称的映射:

$ awk -v map='apple,FRUIT2,tomate,FRUIT3,*,FRUIT4' -f tst.awk file
fruits:FRUIT4,FRUIT2,FRUIT4,FRUIT4,FRUIT4,FRUIT3,FRUIT4
fruits:FRUIT2,FRUIT4,FRUIT4
fruits:FRUIT4,FRUIT4,FRUIT4,FRUIT4
fruits:FRUIT4,FRUIT3,FRUIT4,FRUIT4
fruits:FRUIT4,FRUIT4
fruits:FRUIT2,FRUIT4
fruits:FRUIT4,FRUIT2,FRUIT4

$ awk -v map='apple,BAZINGA,*,VEGGIE' -f tst.awk file
fruits:VEGGIE,BAZINGA,VEGGIE,VEGGIE,VEGGIE,VEGGIE,VEGGIE
fruits:BAZINGA,VEGGIE,VEGGIE
fruits:VEGGIE,VEGGIE,VEGGIE,VEGGIE
fruits:VEGGIE,VEGGIE,VEGGIE,VEGGIE
fruits:VEGGIE,VEGGIE
fruits:BAZINGA,VEGGIE
fruits:VEGGIE,BAZINGA,VEGGIE

$ awk -v map='apple,FRUIT2,tomate,FRUIT3' -f tst.awk file
fruits:banana,FRUIT2,grape,limon,orange,FRUIT3,
fruits:FRUIT2,limon,
fruits:banana,grape,limon,
fruits:orange,FRUIT3,grape,
fruits:banana,
fruits:FRUIT2,
fruits:banana,FRUIT2,

'''your code
Dim key As Variant
For Each key In d
    If Not IsNumeric(key) Then
        MsgBox "dictionary has a text value!"
        Exit Sub
    End If
Next key
'''your code