2009-09-22 110 views
0

我得到一个文档,字段之间用冒号分隔(:),我需要不时更改第二个字段。该文件看起来是这样的:sed:搜索并替换不同的列

name1:UhX.PPFW7$YhPMH0BISY:23490:::::: 
name2:1./0oV$GEs6WJpE$LHXhy:19239:0:29388:2::29302: 
... 

文件的第二场偶尔会发生变化,可能包含一对夫妇正则表达式字符($)和正斜杠。

我想只替换第二个字段,因为随后的数据可能在将来会有所不同。如果我:

sed -e "s~^name2:.*:~name2:aTest\$repl.ace:~g" tst 

文本到第二列的右侧丢失:

name2:aTest$repl.ace: 

(即, '19239:0:29388:2 :: 29302:')。有没有一种方法可以代替变化的列并保留行的其余部分?或者,可能有更好的方案来做到这一点?

回答

0

最简单的方法是改变。 *在您的正则表达式中仅匹配实际出现在第二个字段中的内容,例如:

sed -e "s~^name2:[^:]*:~name2:aTest\$repl.ace:~g" tst 

([^:] * ==任何不包含冒号),或:

sed -e "s~^name2:[$./0-9a-zA-Z]*:~name2:aTest\$repl.ace:~g" tst 

([等等] * ==任何数量列出的字符的)

+0

嘿,那太好了。想知道这是否可能在sed。以为我可能正在看一个更复杂的命令。欣赏提示,安东尼。 –

0

Sed可能不是最好的工具,因为如果真的不知道字段。考虑awk(它有一个内置的领域的概念),而不是:

$ awk -F : 'NF>=2{split($0,a,":");a[2]="new sting";printf(a[1]);for(i=2;i<=NF;i++){printf":%s",a[i]};printf("\n");}' <input file> 

或格式化的可读性:

awk -F : 'NF>=2 { 
        split($0,a,":"); 
        a[2]="new sting"; 
        printf(a[1]); 
        for(i=2;i<=NF;i++){ 
        printf":%s",a[i] 
        }; 
        printf("\n"); 
       }' <input file> 

对于一般性,你可能希望将":"FS取代。另外值得关注的是,如果您编写脚本而不是在命令行上运行,这将使实现更清晰。

本实施方式假定您想要替换全部的第二个字段。如果宇只需要选择一些更换的线条,图案改为

$2=="string to match" 

$2~/regex to match/ 
+0

嘿,AWK当时有点过头了,但它确实有效。谢谢。 –

0

试试这个:

perl -pe 's~^name2:.*?:~name2:aTest\$repl.ace:~g' test 
+0

开始喜欢Perl - 它使用的所有语法(我见过)很容易记住语法。感谢提示ennuikiller。 –