【问题标题】:Converting a text file by replacing words with numbers通过用数字替换单词来转换文本文件
【发布时间】:2017-01-31 23:43:26
【问题描述】:

我有一个 cpp 代码。它基本上需要一个字典文件,格式为:

blue 1
cat 2
chased 3
dog 4
. 5
....

并获取一个文本文件:

blue cat chased dog .
yellow carrot ate brown fish .

并将其转换为:

1 2 3 4 5
88 90 121 11 133 5
...... 

在 Bash 中是否有一个简单的单行解决方案?

【问题讨论】:

  • 你能告诉我们cpp的尝试吗?你对bash到底有什么困难?
  • 有一个简单的awk one-liner。

标签: bash awk sed


【解决方案1】:

awk 来救援!

$ awk 'NR==FNR {dict[$1]=$2; next} 
               {for(i=1;i<=NF;i++) $i=dict[$i]}1' dict file

也许添加处理字典中缺失项的逻辑

【讨论】:

  • 没错!很好的答案。
【解决方案2】:

@choroba 的 sed 解决方案对我不起作用。我不确定是否有一个解决方案。我会在 Bash 中这样做:

#!/bin/bash

# read the word values from the first file into an associative array
declare -A map
while IFS=' ' read -r word value; do
  map[$word]=$value
done < 1.txt

# traverse the second file and print out numbers corresponding to each word
# if there is no mapped number, print nothing
while read -r line; do
  read -ra words <<< "$line"
  for word in ${words[@]}; do
    num="${map[$word]}"
    [[ $num ]] && printf "%s " "${map[$word]}"
  done
  printf "\n"
done < 2.txt

为您的问题中的文件提供以下输出:

1 2 3 4 5
5

【讨论】:

    【解决方案3】:

    为了愚蠢,这里是纯 Bash(恕我直言,您应该使用 awk):

    declare -A dict
    while read k v; do 
        dict[$k]=$v
    done < /tmp/f1.txt
    
    while IFS= read -r line || [[ -n $line ]]; do 
        la=($line)
        for word in ${la[@]}; do 
            [[ ${dict[$word]} ]] && printf "%s " ${dict[$word]}; done
        echo
    done < /tmp/f2.txt  
    

    【讨论】:

      【解决方案4】:

      在 awk 中实现 @karakfa 设想的缺失字典项:

      $ awk 'NR==FNR {
                 a[$1]=$2;                 # store dict to a hash
                 if($2>m)                  # m is the max number in dict
                     m=$2;
                 next
             } {
                 for(i=1;i<=NF;i++)        # iterate thru all words in record
                     if($i in a)           # if a dict match is found
                         $i=a[$i];         # replace it
                     else {                # if not
                         a[$i]=++m;        # grow m and make new dictionary entry
                         # print a[$i], m > "new_items" # to store them to a file
                         $i=m              # ... and use it
                     }
                 } 1' dict text
      

      【讨论】:

        【解决方案5】:

        从输入文件创建一个 sed 脚本:

        sed 's/^/s=/;s/ /=/;s/$/=/' file
        

        并在输入上运行它:

        sed 's/^/s=/;s/ /=/;s/$/=/' file | sed -f- input
        

        如果一个词是另一个词的一部分,这可能不起作用,例如catcategory

        Perl 解决方案:将第一个文件读入哈希表,然后读取第二个文件并将每个单词替换为哈希表中对应的值。

        perl -lane 'if (! $second) { $h{ $F[0] } = $F[1] }
                        else { s/(\S+)/$h{$1}/g; print }
                    $second = 1 if eof;' file input
        

        【讨论】:

        • Perl 解决方案工作正常,但 . 除外 - 它不会将其映射到数字。
        猜你喜欢
        • 2022-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-25
        • 1970-01-01
        • 2015-03-02
        • 1970-01-01
        • 2015-01-30
        相关资源
        最近更新 更多