【问题标题】:Use grep or sed to keep only the words that are in another word list file使用 grep 或 sed 仅保留另一个单词列表文件中的单词
【发布时间】:2021-11-17 08:15:37
【问题描述】:

我有一个句子列表(每行一个句子)和一本字典(一个单词列表,每行一个单词)。我想使用 awk、grep 或 sed 来编辑句子文件,以便只保留我的字典文件中的单词。 例如字典:

hello
dog
lost
I
miss
computer
buy

输入文件:

I miss my dog
I want to buy a new computer

结果:

I miss dog
I buy computer

我知道这可以通过 Python 轻松完成,但我尝试使用终端命令(awk、sed、grep 或任何其他终端命令)。

谢谢。

【问题讨论】:

  • 你会如何在 python 中做到这一点?使其适应 awk。
  • 我知道 Python,但我是 awk、sed、grep 等的初学者并尝试使用它们。在 Python 中,我只需读取单词列表文件,使用单词创建一个字符串列表,然后读取输入文件并输出该单词(如果它存在于数组中)。
  • 请提供足够的代码,以便其他人更好地理解或重现问题。

标签: unix awk sed terminal grep


【解决方案1】:

这是作为伪代码的基本算法。我建议尝试使用 AWK 来实现它:

if (condition) statement [ else statement ] 

while (condition) statement

do statement while (condition)

for (expr1; expr2; expr3) statement

for (var in array) statement

break

continue

【讨论】:

    【解决方案2】:

    在 Python 中,我只需读取单词列表文件,使用单词创建一个字符串列表,然后读取输入文件并输出该单词(如果它存在于数组中)。

    这也是你在awk 中的做法:

    $ awk 'FNR == NR { dict[$0] = 1; next } # Read the dictionary file
           { # And for each word of each line of the sentence file
             for (word = 1; word <= NF; word++) {
               if ($word in dict) # See if it's in the dictionary
                 printf "%s ", $word
             }
             printf "\n"
           }' dict.txt input.txt
    I miss dog
    I buy computer
    

    (这确实会在每一行留下一个尾随空格,但如果重要的话很容易过滤掉)

    【讨论】:

      【解决方案3】:
      awk '
          NR==FNR { dict[$1]; next }
          {
              sent = ""
              for (i=1; i<=NF; i++) {
                  if ($i in dict) {
                      sent = (sent=="" ? "" : sent OFS) $i
                  }
              }
              print sent
          }
      ' dict file
      I miss dog
      I buy computer
      

      三元表达式(sent=="" ? "" : sent OFS) 是为了确保我们不会在将要输出的句子的开头或结尾得到一个虚假的空白字符,如果已经有另一个前面的单词,则只在当前单词之前添加一个空格。

      以上假设匹配应该区分大小写。如果不是,则将dict[$1] 更改为dict[tolower[$1]] 并将$i in dict 更改为tolower($i) in dict。它还假设没有要考虑的标点符号,例如I miss my dog.my dog's friendly。如果这是错误的,请编辑您的问题以提供包含标点符号的示例输入/输出。

      【讨论】:

        【解决方案4】:

        这可能对你有用(GNU sed):

        sed -E 'H;$!d;x;s/.//;y/\n/|/;s/.*/s#\\b(&)\\b#\\n\&#g/' dictionaryFile |
        sed -Ef - -e 's/^(\S+).*/\1/mg;s/\n/ /g;s/.//' textFile
        

        dictionaryFile 制作成一个 sed 命令文件,该文件在该文件中的每个单词前面加上一个换行符。

        在第二次调用 sed 时,使用从第一次调用通过管道传输的 sed 命令文件,然后使用多行替换,删除一行中第一个单词之后的所有内容。

        用空格替换换行符并删除行首的第一个空格并打印结果。

        可以通过在第二个 sed 调用命令中添加 /\S/!d 来消除空行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-23
          • 1970-01-01
          • 1970-01-01
          • 2019-06-24
          • 1970-01-01
          • 2014-03-15
          • 2013-07-11
          • 1970-01-01
          相关资源
          最近更新 更多