通过用数字替换单词来转换文本文件

时间:2017-01-31 23:43:27

标签: bash awk sed

我有一个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中是否有一个简单的单行解决方案?

5 个答案:

答案 0 :(得分:3)

awk救援!

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

或许可以添加用于处理字典中缺失项目的逻辑

答案 1 :(得分:0)

从输入文件创建一个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

答案 2 :(得分:0)

@ 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 :(得分:0)

对于愚蠢,这里是纯粹的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 :(得分:0)

在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