【问题标题】:sed: Search and replace varying columnsed:搜索和替换不同的列
【发布时间】:2009-09-22 02:22:17
【问题描述】:

我得到一个文档,其中字段由冒号 (:) 分隔,我需要不时更改第二个字段。文档如下所示:

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:”)。有没有办法 sed 可以替换不同的列并保留该行的其余部分?或者,是否有更好的程序可以做到这一点?

【问题讨论】:

    标签: bash sed


    【解决方案1】:

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

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

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

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

    ([blah]* == 列出的任意数量的字符)

    【讨论】:

    • 嘿,太好了。想知道这在 sed 中是否可行。以为我可能正在查看一个更复杂的命令。感谢小费,安东尼。
    【解决方案2】:

    Sed 可能不是最好的工具,因为 if 并不真正了解字段。请考虑 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。另外值得一看的是 this join function,如果您编写脚本而不是在命令行上运行,这将使实现更清晰。

    此实现假定您要替换所有第二个字段。如果您只需要选择部分行进行替换,请将模式更改为

    $2=="string to match"
    

    $2~/regex to match/
    

    【讨论】:

    • 呵呵,当时 awk 有点超出我的想象,但它确实有效。谢谢。
    【解决方案3】:

    试试这个:

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

    【讨论】:

    • 开始喜欢 perl - 它使用的所有语法(我见过)都很容易记住语法。感谢您的提示。
    猜你喜欢
    • 2014-09-13
    • 2014-03-14
    • 2010-11-05
    • 2016-04-27
    • 2017-08-02
    • 2021-02-18
    • 2015-01-04
    • 1970-01-01
    相关资源
    最近更新 更多