繁体   English   中英

使用 sed 命令查找和替换单词不起作用

[英]Find and replace words using sed command not working

我有一个制表符分隔的文本文件,第一列包含要找到的单词,第二列包含要替换找到的单词的单词。 一旦找到并替换了该单词,就不应再次更改它。

例如:

adam    a +dam
a   b

所以对于给定的文本文件:

adam played with a ball

我预计:

a +dam played with b ball

但是,我得到:

b +dbm plbyed with b bbll

我正在使用以下 sed 命令来查找和替换:

sed -e 's/^/s%/' -e 's/\t/%/' -e 's/$/%g/' tab_sep_file.txt | sed -f - original_file.txt >replaced.txt

我该如何解决这个问题

您的方法的基本问题是您不想将先前替换中的匹配文本替换为以后的替换 - 您不想将a +dam中的 a 更改为b 这使得sed成为一个非常糟糕的选择 - 你可以创建一个匹配所有你想要替换的东西的正则表达式,但是选择使用哪个替换是一个问题。

一种使用 GNU awk的方法:

gawk -F'\t' '
     FNR == NR { subs[$1] = $2; next } # populate the array of substitutions
     ENDFILE {
             if (FILENAME == ARGV[1]) {
                # Build a regular expression of things to substitute
                subre = "\\<("
                first=0
                for (s in subs)
                    subre = sprintf("%s%s%s", subre, first++ ? "|" : "", s)
                subre = sprintf("%s)\\>", subre)
             }
     }
     {
        # Do the substitution
        nwords = patsplit($0, words, subre, between)
        printf "%s", between[0]
        for (n = 1; n <= nwords; n++)
            printf "%s%s", subs[words[n]], between[n]
        printf "\n"
     }
' tab_sep_file.txt original_file.txt

哪个输出

a +dam played with b ball

首先,它读取 TSV 文件并构建要替换的单词数组和替换为 ( subs ) 的文本。 然后在读取该文件后,它会构建一个正则表达式来匹配所有可能找到的单词 - 在这种情况下是\<(a|adam)\> \<\>仅分别匹配单词的开头和结尾,因此中的a将不匹配。

然后对于包含要处理的文本的第二个文件,它使用patsplit()将每一行拆分为匹配部分( words )和匹配之间的位( between )的数组,并迭代数组的长度,打印输出每个匹配项的替换文本。 这样可以避免重新匹配已经被替换的文本。


还有一个使用相同方法的perl版本:

perl -e '
     my %subs;
     open my $words, "<", shift or die $!;
     while (<$words>) {
        chomp;
        my ($word, $rep) = split "\t" ,$_, 2;
        $subs{$word} = $rep;
     }
     my $subre = "\\b(?:" . join("|", map { quotemeta } keys %subs) . ")\\b";
     while (<<>>) {
       print s/$subre/$subs{$&}/egr;
     }
' tab_sep_file.txt original_file.txt

(这个会转义要替换的单词中的正则表达式元字符,使其更健壮)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM