我有一个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中是否有一个简单的单行解决方案?
答案 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
如果某个单词是另一个单词的一部分,则可能无效,例如: cat
和category
。
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