V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
v2htm
V2EX  ›  程序员

sed+awk 能不能实现根据多列数据批量替换?

  •  
  •   v2htm · 2015-12-08 15:00:11 +08:00 · 3009 次点击
    这是一个创建于 3061 天前的主题,其中的信息可能已经有所发展或是发生改变。
    awk 看起来非常强大,不过有个需求我用 awk 实现不了,难道 awk 做不到?
    string.txt 包含如下列:
    1 word WORD
    2 test TEST
    3 this THIS
    ……

    foo.txt 内容:
    this is a word replace test.

    替换成:
    <3>thisTHIS is a <1>wordWORD replace <3>testTEST.
    10 条回复    2015-12-08 21:12:16 +08:00
    uuspider
        1
    uuspider  
       2015-12-08 15:57:52 +08:00 via iPhone   ❤️ 1
    一行一行地正则+替换呗,不过,为啥必须 sed+awk?
    v2htm
        2
    v2htm  
    OP
       2015-12-08 16:11:49 +08:00
    @uuspider 列表很长,文件很多啊,必须批量替换
    你觉得其他工具用什么最合适?
    SpicyCat
        3
    SpicyCat  
       2015-12-08 17:02:50 +08:00
    楼主的需求我都没看懂。
    lululau
        4
    lululau  
       2015-12-08 17:25:53 +08:00   ❤️ 1
    如果不考虑标点的话:

    gawk -v FS='[^0-9a-zA-Z]' 'NR==FNR { d[$2]="<"$1">"$2$3; next}; {for(i=1;i<=NF;i++) { if(d[$i]) $i = d[$i]};print}' string.txt foo.txt

    如果要考虑保留标点,我觉得用 awk 写有点太复杂了,建议用 Perl/Ruby :

    ruby -pe 'BEGIN{$d=IO.readlines("./string.txt").map(&:split).each_with_object({}){|l,h|h[l[1]]="<%s>%s%s"%l}};gsub(/\w+/) {|s|$d[s]||s}' foo.txt
    reticentfat
        5
    reticentfat  
       2015-12-08 18:10:02 +08:00
    仔细看了三遍没看懂需求
    jings
        6
    jings  
       2015-12-08 18:18:11 +08:00   ❤️ 1
    看了下规律 应该是下面的对应关系吧
    var string={
    test: "<2>testTEST",
    this:"<3>thisTHIS",
    word:"<1>wordWORD",
    }
    binux
        7
    binux  
       2015-12-08 18:31:29 +08:00   ❤️ 2
    echo "this is a word replace test." | awk 'BEGIN { while (getline < "string.txt") { s[$2]="<"$1">"$2$3 } } { for (k in s) { sub(k, s[k], $0) } print $0; }'
    xufang
        8
    xufang  
       2015-12-08 18:41:20 +08:00   ❤️ 1
    列表如果数量不大的话,比如在 2~3 万行,直接用 sublime 的列编辑和正则功能,秒杀之。
    比写脚本还少了调试步骤,又快又直观。
    v2htm
        9
    v2htm  
    OP
       2015-12-08 21:01:13 +08:00
    非常感谢大家!
    @SpicyCat @reticentfat 主要是为了直观起见例子举得毫无可读性和实际意义,实际用途是转换电子书时候批量添加注释:根据一个三列的列表,用第二列匹配若干 html 文件内的字符串,前后分别插入第一列和第三列,实际比这个复杂一点,但核心就是这个。用 sed awk 是因为别的语言我更陌生,自己没法进一步修改。

    @lululau 因为必须要保留标点,所以 awk 那条没测试, ruby 的测试没问题,我只了解一点 sed 和 awk ,其他语言没法自己根据实际需求进一步完善,既然 ruby 这么高效,我还是研究一下!

    @binux 匆忙测试了一下,输出结果还是原文,是不是要用 gsub ?
    binux
        10
    binux  
       2015-12-08 21:12:16 +08:00   ❤️ 1
    @v2htm 我只保证在你给的例子中有效
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   994 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 20:31 · PVG 04:31 · LAX 13:31 · JFK 16:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.