![我必须使用 shell 计算两个文件的值并将结果存储在另一个文件中](https://linux22.com/image/41270/%E6%88%91%E5%BF%85%E9%A1%BB%E4%BD%BF%E7%94%A8%20shell%20%E8%AE%A1%E7%AE%97%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84%E5%80%BC%E5%B9%B6%E5%B0%86%E7%BB%93%E6%9E%9C%E5%AD%98%E5%82%A8%E5%9C%A8%E5%8F%A6%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B8%AD.png)
我必须计算两个文件的值并将结果存储在输出文件中。在输出文件中,每条记录显示输入文件中同名记录的乘积。
文件一
s1 10
s2 20
s3 25
s4 25
s5 25
s6 20
s7 25
s8 25
文件二
s2 4
s1 10
s3 2
s4 3
s6 3
s7 2
s8 2
输出
s1 100
s2 80
s3 50
s4 75
s6 60
s7 50
s8 50
注意:我必须使用外壳。
答案1
这个脚本可以满足您的需要。它假设您的文件始终采用以下格式
id value, id2 value2, id3 value3
也就是说,它假定两个文件之间以逗号分隔的字段和一致的格式。它还假设最新版本bash
支持索引数组。它还给出了正确的输出,即您要求的输出,而不是您显示的输出(例如 2x25 != 75)。
#!/usr/bin/env bash
## Read each line of the first file into the
## array lines1.
mapfile -t lines1 < file1
## Do the same for the 2nd file and the array lines2.
mapfile -t lines2 < file2
declare -A fields2
declare -A fields1
## Iterate through each element of $lines2
## and separate ids from values
for ((i=0; i<${#lines2[@]}; i++)); do
while read id val
do
fields2["$id"]="$val"
done < <(printf "%s\n" "${lines2[$i]//, /$'\n'}")
done
## Iterate through each element of $lines1, separate
## ids from values.
for ((i=0; i<${#lines1[@]}; i++)); do
while read id val
do
## Some ids don't exist in both files, set their
## value to 1 to avoid errors.
if [[ -z "${fields2[$id]}" ]]; then
fields2[$id]=1
fi
## Print the id and the result of the multiplication.
printf "%s %d " $id "$(( ${fields2[$id]} * $val ))";
done < <(printf "%s\n" "${lines1[$i]//, /$'\n'}")
echo "";
done