sed+awk 能不能实现根据多列数据批量替换? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
v2htm

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

  •  
  •   v2htm Dec 8, 2015 3824 views
    This topic created in 3796 days ago, the information mentioned may be changed or developed.
    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 replies    2015-12-08 21:12:16 +08:00
    uuspider
        1
    uuspider  
       Dec 8, 2015 via iPhone   1
    一行一行地正则+替换呗,不过,为啥必须 sed+awk?
    v2htm
        2
    v2htm  
    OP
       Dec 8, 2015
    @uuspider 列表很长,文件很多啊,必须批量替换
    你觉得其他工具用什么最合适?
    SpicyCat
        3
    SpicyCat  
       Dec 8, 2015
    楼主的需求我都没看懂。
    lululau
        4
    lululau  
       Dec 8, 2015   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  
       Dec 8, 2015
    仔细看了三遍没看懂需求
    jings
        6
    jings  
       Dec 8, 2015   1
    看了下规律 应该是下面的对应关系吧
    var string={
    test: "<2>testTEST",
    this:"<3>thisTHIS",
    word:"<1>wordWORD",
    }
    binux
        7
    binux  
       Dec 8, 2015   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  
       Dec 8, 2015   1
    列表如果数量不大的话,比如在 2~3 万行,直接用 sublime 的列编辑和正则功能,秒杀之。
    比写脚本还少了调试步骤,又快又直观。
    v2htm
        9
    v2htm  
    OP
       Dec 8, 2015
    非常感谢大家!
    @SpicyCat @reticentfat 主要是为了直观起见例子举得毫无可读性和实际意义,实际用途是转换电子书时候批量添加注释:根据一个三列的列表,用第二列匹配若干 html 文件内的字符串,前后分别插入第一列和第三列,实际比这个复杂一点,但核心就是这个。用 sed awk 是因为别的语言我更陌生,自己没法进一步修改。

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

    @binux 匆忙测试了一下,输出结果还是原文,是不是要用 gsub ?
    binux
        10
    binux  
       Dec 8, 2015   1
    @v2htm 我只保证在你给的例子中有效
    About     Help     Advertise     Blog     API     FAQ     Solana     2598 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 46ms UTC 11:34 PVG 19:34 LAX 04:34 JFK 07:34
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86